//SetINIForRoute sets the appropriate INI file values for the player's route and location public static INIFile SetINIForRoute(int locationID, Routes.GameRoutes routeToSet) { if (routeToSet >= Routes.GameRoutes.TruePacifistDate) { staticINIFile.skipAsrielStory = true; staticINIFile.floweyChatProgress = 1; staticINIFile.mettatonSkip = true; staticINIFile.fightStage = 7; if (routeToSet == Routes.GameRoutes.TruePacifistEpilogue) { staticINIFile.barrierDestroyed = true; staticINIFile.canTrueReset = true; } } else if (routeToSet == Routes.GameRoutes.Genocide) { staticINIFile.killedSans = MiscFunctions.SetBooleanValueFromLocation(locationID, 231); staticINIFile.timesReachedMid = SetIntegerValue(1, locationID, 231); staticINIFile.timesFoughtSans = SetIntegerValue(1, locationID, 231); staticINIFile.timesHeardIntro = SetIntegerValue(1, locationID, 231); } staticINIFile.timesMetFlowey = SetIntegerValue(1, locationID, 5); staticINIFile.timesMetSans = SetIntegerValue(1, locationID, 45); staticINIFile.timesMetPapyrus = SetIntegerValue(1, locationID, 45); staticINIFile.mettatonSkip = Convert.ToBoolean(SetIntegerValue(1, locationID, 211)); staticINIFile.sansMetInJudgment = Convert.ToBoolean(SetIntegerValue(1, locationID, 231)); return(staticINIFile); }
//CopyAudioToNamed copies the audio file from original, converts it to OGG, then outputs it to the Named folder private void CopyAudioToNamed() { for (int i = 0; i < Constants.GameTracksCount; i++) { if (presetData[i].CustomTrack != "Default") { MiscFunctions.convertToOGG(_OutputPath + "//Original//", _OutputPath + "//Named//", presetData[i].CustomTrack, presetData[i].GameTrack); } } }
//PopulateGameTracks adds all OGG vorbis game tracks from the backup directory to the list private void PopulateGameTracks() { string[] gameTracks = MiscFunctions.GetFilesWithExtensions(Constants.BackupPath, Constants.SupportedFileTypes); for (int i = 0; i < gameTracks.Length; i++) { gameTracks[i] = IDs.GameTracks.GetTrackVisibleName(gameTracks[i]); } Array.Sort(gameTracks); AddListViewItems(gameTracksList, gameTracks); }
//CopyAllAudioToOriginal copies all selected custom tracks from their directory to the Original folder in the preset private void CopyAllAudioToOriginal() { foreach (var file in MiscFunctions.GetFilesWithExtensions(customTrackDirectory, Constants.SupportedFileTypes)) { foreach (var data in presetData) { if (Path.GetFileName(file) == Path.GetFileName(data.CustomTrack)) { File.Copy(file, _OutputPath + "//Original//" + Path.GetFileName(data.CustomTrack), true); } } } }
public static MessageBoxResult Show(Dictionary <Characters, string> messages, Constants.CharacterReactions react, MessageBoxButton buttons) { Characters randChara = MiscFunctions.GetRandomMessageBoxCharacter(new List <Characters>(messages.Keys)); if (XML.characterMessagesSetting == false) { randChara = Characters.None; } UTMessageBoxWindow messageBox = new UTMessageBoxWindow(randChara, react, GetMessageForRandCharacter(randChara, messages), buttons); if (messageBox.ShowDialog() == true) { messageBox.IsClosing = true; return(messageBox.Result); } else { messageBox.IsClosing = true; return(MessageBoxResult.None); } }
//makeSave loops through all UI controls and converts and casts to thisSave variable types as required to create a new save void makeSave() { thisSave.PlayerName = nameBox.Text; thisSave.Location = IDs.Locations.GetRoomID(locationCombo.SelectedItem.ToString()); thisSave.LOVE = Convert.ToInt16(LOVECombo.Text); thisSave.KillCount = Convert.ToInt16(killsBox.Text); thisSave.GOLD = Convert.ToInt16(GOLDBox.Text); thisSave.Weapon = IDs.GetID(weaponCombo.SelectedItem.ToString()); thisSave.Armor = IDs.GetID(armorCombo.SelectedItem.ToString()); thisSave.HP = Convert.ToInt16(HPBox.Text); thisSave.friskAT = Convert.ToInt16(friskATBox.Text) + 10; //For some reason, the game sets Frisk's base AT to -10 of what is set in the thisSave.friskDF = Convert.ToInt16(friskDFBox.Text) + 10; //save file. Am I missing something regarding the AT/DF system? thisSave.weaponAT = Convert.ToInt16(weaponATBox.Text); thisSave.armorDF = Convert.ToInt16(armorDFBox.Text); int i = 0; Array.Clear(thisSave.inventoryItems, 0, thisSave.inventoryItems.Length); foreach (Grid grid in inventoryGrid.Children.OfType <Grid>()) { foreach (ComboBox comboBox in grid.Children.OfType <ComboBox>()) { thisSave.inventoryItems[i] = IDs.GetID(comboBox.SelectedItem.ToString()); i++; } } i = 0; Array.Clear(thisSave.phoneItems, 0, thisSave.phoneItems.Length); foreach (var checkBox in phoneItemsGrid.Children.OfType <CheckBox>()) { if ((bool)checkBox.IsChecked) { thisSave.phoneItems[i] = IDs.GetID(checkBox.Content.ToString()); i++; } } thisSave.SaveName = saveNameBox.Text; thisINI = INI.GetINI(); thisINI.sansMetInJudgment = MiscFunctions.SetBooleanValueFromLocation(thisSave.Location, 232); if (thisSave.Location == 999) { thisINI.photoshopFight = true; } else { thisINI.skipFight = false; } if (thisSave.Location == 998) { thisSave = SAVE.SAVEFile.SetSaveForRoute(thisSave, thisSave.Location, Routes.GameRoutes.Genocide); genocideRadio.IsChecked = true; } if (GetSelectedRoute() >= Routes.GameRoutes.TruePacifistAsrielTalk) { thisINI.barrierDestroyed = true; } if (GetSelectedRoute() == Routes.GameRoutes.TruePacifistEpilogue) { thisINI.canTrueReset = true; } else if (GetSelectedRoute() == Routes.GameRoutes.Genocide) { thisINI.killedSans = MiscFunctions.SetBooleanValueFromLocation(thisSave.Location, 232); } }
//SetSaveForRoute sets the variable values needed for each route's requirements to be met up to the player's currentLocation public static SAVEFile SetSaveForRoute(SAVEFile save, int locationID, Routes.GameRoutes routeToSet) { //It is key to note we assume the maximum kill count allowed for each route, regardless of location //This shouldn't be too big of an issue as the user can manually change their kills via the Editor UI SAVEInstance = save; clearStates(locationID); SAVEInstance.rodeCastleLift = MiscFunctions.SetBooleanValueFromLocation(locationID, 216); SAVEInstance.unlockedCastleChain = MiscFunctions.SetBooleanValueFromLocation(locationID, 226); SAVEInstance.insideCastle = MiscFunctions.SetBooleanValueFromLocation(locationID, 216); SAVEInstance.coreElevatorUnlocked = MiscFunctions.SetBooleanValueFromLocation(locationID, 210); switch (routeToSet) { case Routes.GameRoutes.Family: SetCharacterStates(locationID, CharacterStates.Spared, Characters.Toriel, Characters.Papyrus); SetDateValue(locationID, Characters.Papyrus, DateStates.PapyrusComplete); SetDateValue(locationID, Characters.Undyne, DateStates.UndyneComplete); SAVEInstance.undyneOnPhone = MiscFunctions.SetBooleanValueFromLocation(locationID, 139); SAVEInstance.KillCount = 0; break; case Routes.GameRoutes.BetrayedUndyneDated: SetCharacterStates(locationID, CharacterStates.Spared, Characters.Toriel, Characters.Papyrus); SetDateValue(locationID, Characters.Undyne, DateStates.UndyneComplete); SetDateValue(locationID, Characters.Papyrus, DateStates.PapyrusComplete); SAVEInstance.undyneOnPhone = MiscFunctions.SetBooleanValueFromLocation(locationID, 139); SAVEInstance.KillCount = 9; break; case Routes.GameRoutes.BetrayedUndyneNoDate: SetCharacterStates(locationID, CharacterStates.Spared, Characters.Toriel, Characters.Papyrus); SetDateValue(locationID, Characters.Undyne, DateStates.DateNotStarted); SetDateValue(locationID, Characters.Papyrus, DateStates.PapyrusComplete); SAVEInstance.KillCount = 9; break; case Routes.GameRoutes.BetrayedUndyneMettaton: SetDateValue(locationID, Characters.Undyne, DateStates.DateNotStarted); SetCharacterStates(locationID, CharacterStates.Spared, Characters.Toriel, Characters.Papyrus); SetCharacterStates(locationID, CharacterStates.Killed, Characters.Mettaton); SAVEInstance.KillCount = 1; break; case Routes.GameRoutes.ExiledNoUndyneNoPapyrus: SetCharacterStates(locationID, CharacterStates.Spared, Characters.Toriel); SetCharacterStates(locationID, CharacterStates.Killed, Characters.Papyrus, Characters.Undyne); SAVEInstance.KillCount = 2; break; case Routes.GameRoutes.ExiledNoUndynePapyrus: SetCharacterStates(locationID, CharacterStates.Spared, Characters.Toriel, Characters.Papyrus); SetCharacterStates(locationID, CharacterStates.Killed, Characters.Undyne); SAVEInstance.KillCount = 1; break; case Routes.GameRoutes.ExiledUndyneNoPapyrus: SetCharacterStates(locationID, CharacterStates.Spared, Characters.Toriel); SetCharacterStates(locationID, CharacterStates.Killed, Characters.Papyrus); SAVEInstance.KillCount = 1; break; case Routes.GameRoutes.ExiledMonsters: SAVEInstance.KillCount = 10; break; case Routes.GameRoutes.QueenUndyne: SetCharacterStates(locationID, CharacterStates.Spared, Characters.Papyrus); SetCharacterStates(locationID, CharacterStates.Killed, Characters.Toriel); SAVEInstance.KillCount = 1; break; case Routes.GameRoutes.QueenUndyneNoPapyrus: SetCharacterStates(locationID, CharacterStates.Killed, Characters.Toriel, Characters.Papyrus); SAVEInstance.KillCount = 2; break; case Routes.GameRoutes.KingMettaton: SetCharacterStates(locationID, CharacterStates.Spared, Characters.Papyrus); SetCharacterStates(locationID, CharacterStates.Killed, Characters.Toriel, Characters.Undyne); SAVEInstance.KillCount = 2; break; case Routes.GameRoutes.KingMettatonNoPapyrus: SetCharacterStates(locationID, CharacterStates.Killed, Characters.Toriel, Characters.Undyne, Characters.Papyrus); SAVEInstance.KillCount = 3; break; case Routes.GameRoutes.KingPapyrus: SetCharacterStates(locationID, CharacterStates.Spared, Characters.Papyrus); SetCharacterStates(locationID, CharacterStates.Killed, Characters.Toriel, Characters.Undyne, Characters.Mettaton); SAVEInstance.KillCount = 3; break; case Routes.GameRoutes.KingDog: SetCharacterStates(locationID, CharacterStates.Killed, Characters.Toriel, Characters.Undyne, Characters.Mettaton, Characters.Papyrus); SAVEInstance.KillCount = 4; break; case Routes.GameRoutes.Leaderless: SetCharacterStates(locationID, CharacterStates.Killed, Characters.Toriel, Characters.Undyne, Characters.Mettaton, Characters.Papyrus, Characters.RuinsDummy, Characters.Doggo, Characters.Shyren, Characters.BroGuards); SAVEInstance.KillCount = 8; break; case Routes.GameRoutes.QueenAlphys: SetMurderLevel(locationID, 12); SetCharacterStates(locationID, CharacterStates.Killed, Characters.Mettaton); SAVEInstance.KillCount = SAVEInstance.KillCount + 1; //We add one to account for Mettaton being killed break; case Routes.GameRoutes.Genocide: SetMurderLevel(locationID, 16); SAVEInstance.disableAlphysCalls = MiscFunctions.SetBooleanValueFromLocation(locationID, 133); SAVEInstance.disableHotlandPuzzles = MiscFunctions.SetBooleanValueFromLocation(locationID, 133); SAVEInstance.coreElevatorUnlocked = MiscFunctions.SetBooleanValueFromLocation(locationID, 133); SAVEInstance.randomCountersDisabled = MiscFunctions.SetBooleanValueFromLocation(locationID, 212); break; case Routes.GameRoutes.TruePacifistDate: SetCharacterStates(locationID, CharacterStates.Spared, Characters.All); //These used to be just Toriel and Papyrus! Any reason? SetDateValue(236, Characters.Papyrus, DateStates.PapyrusComplete); SetDateValue(236, Characters.Undyne, DateStates.UndyneComplete); SAVEInstance.pacifistStage = 2; SAVEInstance.Location = 236; SAVEInstance.dateAlphysFlag = true; SAVEInstance.rodeCastleLift = true; SAVEInstance.unlockedCastleChain = true; SAVEInstance.undyneOnPhone = true; break; case Routes.GameRoutes.TruePacifistLab: SetCharacterStates(locationID, CharacterStates.Spared, Characters.All); SetDateValue(236, Characters.Papyrus, DateStates.PapyrusComplete); SetDateValue(236, Characters.Undyne, DateStates.UndyneComplete); SAVEInstance.pacifistStage = 11; SAVEInstance.Location = 139; SAVEInstance.rodeCastleLift = true; SAVEInstance.unlockedCastleChain = true; SAVEInstance.undyneOnPhone = true; SAVEInstance.randomCountersDisabled = true; break; case Routes.GameRoutes.TruePacifistAsriel: SetCharacterStates(locationID, CharacterStates.Spared, Characters.All); SetDateValue(236, Characters.Papyrus, DateStates.PapyrusComplete); SetDateValue(236, Characters.Undyne, DateStates.UndyneComplete); SAVEInstance.pacifistStage = 12; SAVEInstance.Location = 216; SAVEInstance.rodeCastleLift = true; SAVEInstance.unlockedCastleChain = true; SAVEInstance.beatTrueLab = true; SAVEInstance.undyneOnPhone = true; SAVEInstance.randomCountersDisabled = true; break; case Routes.GameRoutes.TruePacifistAsrielTalk: SetCharacterStates(locationID, CharacterStates.Spared, Characters.All); SetDateValue(236, Characters.Papyrus, DateStates.PapyrusComplete); SetDateValue(236, Characters.Undyne, DateStates.UndyneComplete); SAVEInstance.pacifistStage = 12; SAVEInstance.Location = 331; SAVEInstance.rodeCastleLift = true; SAVEInstance.unlockedCastleChain = true; SAVEInstance.beatTrueLab = true; SAVEInstance.undyneOnPhone = true; SAVEInstance.randomCountersDisabled = true; break; case Routes.GameRoutes.TruePacifistEpilogue: SetCharacterStates(locationID, CharacterStates.Spared, Characters.All); SetDateValue(236, Characters.Papyrus, DateStates.PapyrusComplete); SetDateValue(236, Characters.Undyne, DateStates.UndyneComplete); SAVEInstance.pacifistStage = 12; SAVEInstance.Location = 236; SAVEInstance.rodeCastleLift = true; SAVEInstance.unlockedCastleChain = true; SAVEInstance.beatTrueLab = true; SAVEInstance.asrielDefeated = true; SAVEInstance.undyneOnPhone = true; SAVEInstance.randomCountersDisabled = true; break; } SetPhoneItems(locationID, routeToSet); SetPlotValue(routeToSet, locationID); return(SAVEInstance); }
//WriteSaveFile writes, well, the save file. public static bool WriteSaveFile(SAVEFile fileToWrite, INI.INIFile ini) { //SetFlagFromBool converts a boolean variable or value to a string to be written as a flag in file0 string SetFlagFromBool(bool booleanToCheck, int valueToSet = 1) { if (booleanToCheck) { return(valueToSet.ToString()); } else { return("0"); } } //We use an ordered dictionary with the key as the line number in file0 to write the value to OrderedDictionary file0Contents = new OrderedDictionary { { 1, fileToWrite.PlayerName }, { 2, fileToWrite.LOVE.ToString() }, { 3, fileToWrite.HP.ToString() }, { 4, "0" }, { 5, fileToWrite.friskAT.ToString() }, { 6, fileToWrite.weaponAT.ToString() }, { 7, fileToWrite.friskDF.ToString() }, { 8, fileToWrite.armorDF.ToString() }, { 9, "4" }, { 10, fileToWrite.EXP.ToString() }, { 11, fileToWrite.GOLD.ToString() }, { 12, fileToWrite.KillCount.ToString() }, { 13, fileToWrite.inventoryItems[0].ToString() }, { 14, fileToWrite.phoneItems[0].ToString() }, { 15, fileToWrite.inventoryItems[1].ToString() }, { 16, fileToWrite.phoneItems[1].ToString() }, { 17, fileToWrite.inventoryItems[2].ToString() }, { 18, fileToWrite.phoneItems[2].ToString() }, { 19, fileToWrite.inventoryItems[3].ToString() }, { 20, fileToWrite.phoneItems[3].ToString() }, { 21, fileToWrite.inventoryItems[4].ToString() }, { 22, "0" }, { 23, fileToWrite.inventoryItems[5].ToString() }, { 24, "0" }, { 25, fileToWrite.inventoryItems[6].ToString() }, { 26, "0" }, { 27, fileToWrite.inventoryItems[7].ToString() }, { 28, "0" }, { 29, fileToWrite.Weapon }, { 30, fileToWrite.Armor }, { 38, Convert.ToInt16(fileToWrite.asrielDefeated) }, { 39, Convert.ToInt16(fileToWrite.randomCountersDisabled) }, { 45, (int)fileToWrite.ruinsDummyState }, { 76, (int)fileToWrite.torielState }, { 83, (int)fileToWrite.doggoState }, { 84, (int)fileToWrite.dogamyState }, { 85, (int)fileToWrite.greaterDogState }, { 88, (int)fileToWrite.comedianState }, { 98, (int)fileToWrite.papyrusState }, { 112, (int)fileToWrite.shyrenState }, { 119, (int)fileToWrite.papyrusDated }, { 232, fileToWrite.KillCount }, { 233, fileToWrite.ruinsKills }, { 234, fileToWrite.snowdinKills }, { 235, fileToWrite.waterfallKills }, { 236, fileToWrite.hotlandKills }, { 282, (int)fileToWrite.undyneState }, { 283, (int)fileToWrite.madDummyState }, { 381, (int)fileToWrite.undyneState }, { 398, Convert.ToInt16(fileToWrite.disableAlphysCalls) }, { 399, Convert.ToInt16(fileToWrite.disableAlphysCalls) }, { 402, Convert.ToInt16(fileToWrite.disableHotlandPuzzles) }, { 404, Convert.ToInt16(fileToWrite.disableHotlandPuzzles) }, { 405, Convert.ToInt16(fileToWrite.disableHotlandPuzzles) }, { 406, Convert.ToInt16(fileToWrite.disableHotlandPuzzles) }, { 420, (int)fileToWrite.undyneDated }, { 428, (int)fileToWrite.muffetState }, { 430, Convert.ToInt16(fileToWrite.disableHotlandPuzzles) }, { 431, Convert.ToInt16(fileToWrite.disableHotlandPuzzles) }, { 433, (int)fileToWrite.broGuardsState }, { 449, SetFlagFromBool(fileToWrite.coreElevatorUnlocked) }, { 456, (int)fileToWrite.mettatonState }, { 462, SetFlagFromBool(fileToWrite.insideCastle) }, { 463, SetFlagFromBool(fileToWrite.rodeCastleLift) }, { 481, SetFlagFromBool(ini.skipAsrielStory, 17) }, { 483, SetFlagFromBool(fileToWrite.unlockedCastleChain) }, { 484, SetFlagFromBool(fileToWrite.unlockedCastleChain) }, { 485, SetFlagFromBool(fileToWrite.unlockedCastleChain) }, { 486, SetFlagFromBool(ini.skipAsrielStory) }, { 487, SetFlagFromBool(ini.skipAsrielStory, 2) }, { 496, Convert.ToInt16(fileToWrite.undyneOnPhone) }, { 510, SetFlagFromBool(fileToWrite.asrielDefeated, 2) }, { 512, SetFlagFromBool(fileToWrite.beatTrueLab, 3) }, { 513, SetFlagFromBool(fileToWrite.beatTrueLab, 3) }, { 514, SetFlagFromBool(fileToWrite.beatTrueLab, 3) }, { 515, SetFlagFromBool(fileToWrite.beatTrueLab, 3) }, { 516, SetFlagFromBool(fileToWrite.beatTrueLab) }, { 517, SetFlagFromBool(fileToWrite.beatTrueLab, 10) }, { 518, SetFlagFromBool(fileToWrite.beatTrueLab, 0) }, { 519, SetFlagFromBool(fileToWrite.beatTrueLab) }, { 520, SetFlagFromBool(fileToWrite.beatTrueLab) }, { 521, SetFlagFromBool(fileToWrite.beatTrueLab) }, { 522, SetFlagFromBool(fileToWrite.beatTrueLab) }, { 523, SetFlagFromBool(fileToWrite.dateAlphysFlag) }, { 524, fileToWrite.pacifistStage }, { 543, fileToWrite.Plot }, { 544, "1" }, { 545, "1" }, { 546, SetFlagFromBool(MiscFunctions.SetBooleanValueFromLocation(fileToWrite.Location, 12)) }, //Cell Phone { 547, "0" }, { 548, fileToWrite.Location.ToString() }, { 549, "0" } }; if (fileToWrite.Location == 998) { fileToWrite.Location = 235; FileOperations.setGenocide(GenocideStates.Abyss); } else if (fileToWrite.Location == 999) { fileToWrite.Location = 237; } try { StreamWriter file0Writer = new StreamWriter(File.Open(Constants.SavesPath + fileToWrite.SaveName + "//file0", FileMode.Create), Encoding.ASCII); //We iterate through every line and key in file0Contents and if the key value matches lineNumber, we write the corresponding value for (int lineNumber = 1; lineNumber <= 549; lineNumber++) { foreach (DictionaryEntry file0Entry in file0Contents) { if ((int)file0Entry.Key == lineNumber) { file0Writer.WriteLine(file0Entry.Value.ToString()); break; } else if ((int)file0Entry.Key > lineNumber) { file0Writer.WriteLine("0"); break; } } } file0Writer.Close(); if (fileToWrite.Location >= 238 || fileToWrite.Plot >= 208) { File.Copy(Constants.SavesPath + fileToWrite.SaveName + "//file0", Constants.SavesPath + fileToWrite.SaveName + "//file8", true); } return(true); } catch (Exception ex) { System.Windows.MessageBox.Show("An exception occurred when writing the save file. Cannot continue. The exception was: \n\n" + ex, "Error!", MessageBoxButton.OK, MessageBoxImage.Error); return(false); } }
//PopulateGameTracks adds all audio files from the specified dir to the list private void PopulateCustomTracks(string dir) { AddListViewItems(customTracksList, MiscFunctions.GetFilesWithExtensions(dir, Constants.SupportedFileTypes)); }