Example #1
0
            public static double GetPlotForRoom(int ID, Routes.GameRoutes route)
            {
                double plot = 0;

                foreach (var room in plotDict)
                {
                    if (room.Key <= ID)
                    {
                        if (route != Routes.GameRoutes.Genocide)
                        {
                            plot = room.Value.Item1;
                        }

                        else
                        {
                            plot = room.Value.Item2;
                        }
                    }

                    else if (room.Key > ID)
                    {
                        break;
                    }
                }

                return(plot);
            }
Example #2
0
        //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);
        }
Example #3
0
            //SetPhoneItems sets the appropriate phone items for the player's currentLocation and their currentRoute
            //This can be overridden by the user if they change the CheckBoxes manually in the Editor UI
            private static void SetPhoneItems(int currentLocation, Routes.GameRoutes currentRoute)
            {
                int i = 0;

                Array.Clear(SAVEInstance.phoneItems, 0, SAVEInstance.phoneItems.Length);
                if (currentLocation > 11)
                {
                    //We are past the Tension room so we add Toriel's number
                    SAVEInstance.phoneItems[i] = 206;
                    i++;

                    if ((currentLocation > 142 && currentRoute != Routes.GameRoutes.QueenAlphys && currentRoute != Routes.GameRoutes.Genocide) || currentRoute >= Routes.GameRoutes.TruePacifistDate)
                    {
                        //We've passed the Hotland Lab on an appropriate route so we add the Dimensional Boxes
                        SAVEInstance.phoneItems[i] = 220;
                        i++;
                        SAVEInstance.phoneItems[i] = 221;
                        i++;
                    }
                }

                if ((SAVEInstance.papyrusDated == DateStates.PapyrusComplete && SAVEInstance.papyrusState != CharacterStates.Killed) || currentRoute >= Routes.GameRoutes.TruePacifistDate)
                {
                    //Papyrus isn't dead and has been dated so we add his number
                    SAVEInstance.phoneItems[i] = 210;
                }
            }
        //updateCurrentRoute sets up the UI, SAVE and INI files, as well as the selectedRoute when the game route is changed via the UI
        void updateCurrentRoute()
        {
            makeSave();
            Routes.GameRoutes selectedRoute = GetSelectedRoute();

            thisSave = SAVE.SAVEFile.SetSaveForRoute(thisSave, IDs.Locations.GetRoomID(locationCombo.SelectedItem.ToString()), selectedRoute);
            thisINI  = INI.SetINIForRoute(IDs.Locations.GetRoomID(locationCombo.SelectedItem.ToString()), selectedRoute);

            loadSAVE(thisSave);
            loadINI();
            LOVEChanged();
        }
        //We use the loadButton_Click event to open a new folder browser to allow the user to load a save and set up the UI for the loaded save
        private void loadButton_Click(object sender, RoutedEventArgs e)
        {
            FolderBrowser2 directoryFolderBrowser = new FolderBrowser2();

            directoryFolderBrowser.ShowDialog(null);

            if (File.Exists(directoryFolderBrowser.DirectoryPath + "//file0"))
            {
                SAVE.SAVEFile saveFile = SAVE.SAVEFile.LoadSaveFile(directoryFolderBrowser.DirectoryPath);
                loadSAVE(saveFile);
                thisINI = INI.ReadINI(saveFile);
                loadINI();

                Routes.GameRoutes closestRoute = SAVE.SAVEFile.GetClosestRoute(saveFile);

                if (closestRoute == Routes.GameRoutes.Genocide)
                {
                    genocideRadio.IsChecked = true;
                }

                else if (closestRoute >= Routes.GameRoutes.TruePacifistDate)
                {
                    pacifistRadio.IsChecked = true;
                    routeCombo.SelectedItem = Routes.GetEnumDescription(SAVE.SAVEFile.GetClosestRoute(thisSave));
                }

                else
                {
                    neutralRadio.IsChecked  = true;
                    routeCombo.SelectedItem = Routes.GetEnumDescription(SAVE.SAVEFile.GetClosestRoute(thisSave));
                }

                MXA2SE.play_sound(soundEngine, "Assets//Sounds//fileLoaded.wav");
            }

            else
            {
                Dictionary <Characters, string> messageDict = new Dictionary <Characters, string>()
                {
                    { Characters.Alphys, "S-s-sorry, that folder doesn't contain a valid Undertale save file." },
                    { Characters.Asgore, "Human, I'm sorry, but folder doesn't contain a valid Undertale save file." },
                    { Characters.Asriel, "I'm really sorry, I tried, but couldn't find a valid Undertale save file in that folder." },
                    { Characters.Flowey, "YOU. IDIOT! That folder doesn't contain a valid Undertale save file!" },
                    { Characters.Papyrus, "NYOO HOO HOO. I, THE GREAT PAPYRUS, HAVE FAILED TO FIND A VALID SAVE FILE IN THAT FOLDER." },
                    { Characters.Sans, "heyo, pal. try again. i couldn't find an Undertale save file in that folder." },
                    { Characters.Toriel, "My child, I am sorry, but I was unable to find a valid Undertale save file in that folder." },
                    { Characters.Undyne, "HEY, PUNK! I CAN'T FIND AN UNDERTALE SAVE FILE IN THAT FOLDER!" },
                    { Characters.None, "The folder specified does not contain a valid Undertale save file!" }
                };

                UTMessageBox.Show(messageDict, Constants.CharacterReactions.Negative, MessageBoxButton.OK);
            }
        }
Example #6
0
            //SetPlotValue sets the appropriate plot value based on the player's route and their currentLocation
            private static void SetPlotValue(Routes.GameRoutes route, int currentLocation)
            {
                if (route >= Routes.GameRoutes.TruePacifistDate && route < Routes.GameRoutes.TruePacifistEpilogue)
                {
                    SAVEInstance.Plot = 208;
                }

                else if (route == Routes.GameRoutes.TruePacifistEpilogue)
                {
                    SAVEInstance.Plot = 999;
                }

                else
                {
                    SAVEInstance.Plot = IDs.Locations.GetPlotForRoom(currentLocation, route);
                }
            }
Example #7
0
            //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);
            }
Example #8
0
            //SetDateValue sets the corresponding character to the date state passed in. Consult IDs.cs to see the DateStates enum
            private static void SetDateValue(int currentLocation, Characters character, DateStates stateToSet, Routes.GameRoutes route = Routes.GameRoutes.Family)
            {
                //We call CheckRoomForDate to see if the character's date state would be invalid at the player's currentLocation
                //i.e. Undyne cannot possibly be dated if we're still in Snowdin, so if that's the case, we set the stateToSet to DateNotStarted
                if (!Routes.CheckRoomForDate(currentLocation, character, route))
                {
                    stateToSet = DateStates.DateNotStarted;
                }

                switch (character)
                {
                case Characters.Papyrus:
                    SAVEInstance.papyrusDated = stateToSet;
                    break;

                case Characters.Undyne:
                    SAVEInstance.undyneDated = stateToSet;
                    break;
                }
            }
Example #9
0
            //GetClosestEnding checks variables within the SAVEFile and returns the route that most closely matches the SAVEFile content
            public static Routes.GameRoutes GetClosestRoute(SAVEFile actualSave)
            {
                Dictionary <Routes.GameRoutes, int> likenessDict = new Dictionary <Routes.GameRoutes, int>();

                int likeness = 0;

                if (actualSave.pacifistStage == 2)
                {
                    return(Routes.GameRoutes.TruePacifistDate);
                }

                else if (actualSave.pacifistStage == 11)
                {
                    return(Routes.GameRoutes.TruePacifistLab);
                }

                else if (actualSave.pacifistStage == 12)
                {
                    if (actualSave.Location == 331)
                    {
                        return(Routes.GameRoutes.TruePacifistAsrielTalk);
                    }

                    else if (actualSave.asrielDefeated)
                    {
                        return(Routes.GameRoutes.TruePacifistEpilogue);
                    }

                    else
                    {
                        return(Routes.GameRoutes.TruePacifistAsriel);
                    }
                }

                else if (actualSave.disableAlphysCalls && actualSave.disableHotlandPuzzles)
                {
                    return(Routes.GameRoutes.Genocide);
                }

                else
                {
                    Routes.GameRoutes[] routesToIgnore = new Routes.GameRoutes[] { Routes.GameRoutes.TruePacifistDate, Routes.GameRoutes.TruePacifistLab, Routes.GameRoutes.TruePacifistAsriel, Routes.GameRoutes.TruePacifistAsrielTalk, Routes.GameRoutes.TruePacifistEpilogue };
                    foreach (Routes.GameRoutes route in Enum.GetValues(typeof(Routes.GameRoutes)))
                    {
                        if (!routesToIgnore.Contains(route))
                        {
                            SAVEFile compareSave = new SAVEFile();
                            compareSave = SetSaveForRoute(compareSave, actualSave.Location, route);

                            foreach (var actualCharacterState in compareSave.GetType().GetProperties())
                            {
                                foreach (CharacterStates stateToCheck in Enum.GetValues(typeof(CharacterStates)))
                                {
                                    if ((CharacterStates)actualCharacterState.GetValue(actualCharacterState) == stateToCheck)
                                    {
                                        likeness++;
                                    }
                                }
                            }

                            foreach (var actualDateState in compareSave.GetType().GetProperties())
                            {
                                foreach (DateStates stateToCheck in Enum.GetValues(typeof(DateStates)))
                                {
                                    if ((DateStates)actualDateState.GetValue(actualDateState) == stateToCheck)
                                    {
                                        likeness++;
                                    }
                                }
                            }

                            if (compareSave.KillCount <= actualSave.KillCount)
                            {
                                likeness++;
                            }

                            if (Routes.GetMurderLevelForLocation(compareSave.Location, 16) == Routes.GetMurderLevelForLocation(actualSave.Location, 16))
                            {
                                likeness++;
                            }

                            likenessDict.Add(route, likeness);
                            likeness = 0;
                        }
                    }
                }

                return(likenessDict.Where(key => key.Value == likenessDict.Max(value => value.Value)).Select(key => key.Key).FirstOrDefault());
            }