public static string NextJijiHint()
        {
            string hint = string.Empty;

            bool ValidHintItem(string item)
            {
                ReqDef def = LogicManager.GetItemDef(item);

                if (def.majorItem)
                {
                    return(true);
                }
                else if (def.action == GiveItemActions.GiveAction.Kingsoul)
                {
                    return(true);
                }
                else if (def.action == GiveItemActions.GiveAction.Dreamer)
                {
                    return(true);
                }
                else if (item == "Focus")
                {
                    return(true);
                }

                return(false);
            }

            while (RandomizerMod.Instance.Settings.JijiHintCounter < RandomizerMod.Instance.Settings.MaxOrder)
            {
                string location = RandomizerMod.Instance.Settings.GetNthLocation(RandomizerMod.Instance.Settings.JijiHintCounter);
                string item     = RandomizerMod.Instance.Settings.GetNthLocationItems(RandomizerMod.Instance.Settings.JijiHintCounter).FirstOrDefault(i => ValidHintItem(i));
                if (string.IsNullOrEmpty(item) || string.IsNullOrEmpty(location))
                {
                    RandomizerMod.Instance.Settings.JijiHintCounter++;
                    continue;
                }
                else if (RandomizerMod.Instance.Settings.CheckItemFound(item))
                {
                    hint = CreateJijiHint(item, location);
                    RandoLogger.LogHintToTracker(hint);
                    RandomizerMod.Instance.Settings.JijiHintCounter++;
                    continue;
                }
                else
                {
                    hint = CreateJijiHint(item, location);
                    RandoLogger.LogHintToTracker(hint);
                    RandomizerMod.Instance.Settings.JijiHintCounter++;
                    break;
                }
            }
            if (string.IsNullOrEmpty(hint))
            {
                return("Oh! I guess I couldn't find any items you left behind. Since you're doing so well, though, I think I'll be keeping this meal.");
            }
            return(hint);
        }
        public static void SceneChanged(Scene newScene)
        {
            RecalculateRandom();

            // Critical changes for randomizer functionality
            {
                RandomizerChanges.ApplyRandomizerChanges(newScene);
                RandomizerChanges.FixSoftlocks(newScene);
                RandomizerChanges.EditStagStations(newScene);
                RandomizerChanges.EditCorniferAndIselda(newScene);
                RandomizerChanges.DeleteCollectorGrubs(newScene);
            }

            // Transition fixes: critical changes for transition randomizer functionality, protected by bool checks so they can also be used for item randomizer if necessary
            // Control fixes: npc quests that could otherwise be broken with out-of-sequence rooms
            {
                TransitionFixes.ApplyTransitionFixes(newScene);
                TransitionFixes.ApplyControlFixes(newScene);
            }

            // QoL Fixes - hints of all types, lemm sell all, fast grubfather, fast dream nail cutscene, etc
            {
                QoLFixes.MiscQoLChanges(newScene);
                QoLFixes.ApplyHintChanges(newScene);
            }

            // Mainly restores pogos, etc., that were removed by TC
            {
                SkipFixes.FixMiscSkips(newScene);
            }

            {
                DreamPlantEdits.ReplaceDreamPlantOrbs(newScene);
            }

            // Restores all lever skips which were possible on patch 1221
            if (RandomizerMod.Instance.Settings.LeverSkips)
            {
                SkipFixes.FixLeverSkips(newScene);
            }

            // make sure log is regularly updated with game info
            RandoLogger.UpdateHelperLog();
        }
        public static string NextJijiHint()
        {
            int    hintMax      = RandomizerMod.Instance.Settings.Hints.Length;
            string hintItemName = string.Empty;
            string hintItemSpot = string.Empty;
            string hint         = string.Empty;

            while (RandomizerMod.Instance.Settings.JijiHintCounter < hintMax - 1)
            {
                string item     = RandomizerMod.Instance.Settings.Hints[RandomizerMod.Instance.Settings.JijiHintCounter].Item1;
                string location = RandomizerMod.Instance.Settings.Hints[RandomizerMod.Instance.Settings.JijiHintCounter].Item2;
                hint = CreateJijiHint(item, location);
                RandoLogger.LogHintToTracker(hint);

                if (Actions.RandomizerAction.AdditiveBoolNames.TryGetValue(item, out string additiveBoolName))
                {
                    if (!RandomizerMod.Instance.Settings.GetBool(false, additiveBoolName))
                    {
                        hintItemName = item;
                        hintItemSpot = location;
                        RandomizerMod.Instance.Settings.JijiHintCounter++;
                        break;
                    }
                }
                else if (!PlayerData.instance.GetBool(LogicManager.GetItemDef(item).boolName))
                {
                    hintItemName = item;
                    hintItemSpot = location;
                    RandomizerMod.Instance.Settings.JijiHintCounter++;
                    break;
                }
                RandomizerMod.Instance.Settings.JijiHintCounter++;
            }
            if (hintItemName == string.Empty || hintItemSpot == string.Empty || hint == string.Empty)
            {
                return("Oh! I guess I couldn't find any items you left behind. Since you're doing so well, though, I think I'll be keeping this meal.");
            }

            return(hint);
        }
        public static void AddItem(string item, string location)
        {
            if (canvas == null)
            {
                Create();
            }

            item = RandomizerMod.Instance.Settings.GetEffectiveItem(item);

            string itemName = Language.Language.Get(LogicManager.GetItemDef(item).nameKey, "UI");
            string areaName = LogicManager.ShopNames.Contains(location)
                ? location.Replace('_', ' ')
                : RandoLogger.CleanAreaName(LogicManager.GetItemDef(location).areaName);

            string msg = itemName + "\nfrom " + areaName;

            GameObject basePanel = CanvasUtil.CreateBasePanel(canvas,
                                                              new CanvasUtil.RectData(new Vector2(200, 50), Vector2.zero,
                                                                                      new Vector2(0.9f, 0.9f), new Vector2(0.9f, 0.9f)));

            string spriteKey = LogicManager.GetItemDef(item).shopSpriteKey;

            CanvasUtil.CreateImagePanel(basePanel, RandomizerMod.GetSprite(spriteKey),
                                        new CanvasUtil.RectData(new Vector2(50, 50), Vector2.zero, new Vector2(0f, 0.5f),
                                                                new Vector2(0f, 0.5f)));
            CanvasUtil.CreateTextPanel(basePanel, msg, 24, TextAnchor.MiddleLeft,
                                       new CanvasUtil.RectData(new Vector2(400, 100), Vector2.zero,
                                                               new Vector2(1.2f, 0.5f), new Vector2(1.2f, 0.5f)),
                                       CanvasUtil.GetFont("Perpetua"));

            items.Enqueue(basePanel);
            if (items.Count > MaxItems)
            {
                Object.Destroy(items.Dequeue());
            }

            UpdatePositions();
        }
Exemple #5
0
        public static string GetQuirrelHint(string key, string sheetTitle)
        {
            RandomizerMod.Instance.Settings.QuirrerHintCounter++;
            string        hint      = string.Empty;
            List <string> areas     = new List <string>();
            List <string> locations = new List <string>();

            switch (key)
            {
            case "QUIRREL_MEET_TEMPLE_C":
                locations = RandomizerMod.Instance.Settings.ItemPlacements.Where(pair => new List <string> {
                    "Dream_Nail", "Dream_Gate", "Awoken_Dream_Nail"
                }.Contains(pair.Item1)).Select(pair => pair.Item2).ToList();
                foreach (string location in locations)
                {
                    if (LogicManager.ShopNames.Contains(location))
                    {
                        areas.Add("a shop");
                    }
                    else
                    {
                        areas.Add(LogicManager.GetItemDef(location).areaName.Replace('_', ' '));
                    }
                }
                hint = "A great stone egg, lying in the corpse of an ancient kingdom. And this egg...Is it warm? It certainly gives off a unique air." +
                       "<page>" + "Can it be opened? There are strange marks all over it..." +
                       "<page>" + "Perhaps...I've heard rumors of artifacts in this kingdom which can open the mind and recover even the darkest of secrets." +
                       "<page>" + "The first was said to be stowed away in " + areas[0] + "." +
                       "<page>" + "The second kept safe in " + areas[1] + "." +
                       "<page>" + "And the last... somewhere in " + areas[2] + "." +
                       "<page>" + "Perhaps with one of those you might solve the riddle of this temple...";
                break;

            case "QUIRREL_GREENPATH_1":
                locations.Add(RandomizerMod.Instance.Settings.ItemPlacements.First(pair => pair.Item1 == "Mantis_Claw" || pair.Item1 == "Monarch_Wings").Item2);
                foreach (string location in locations)
                {
                    if (LogicManager.ShopNames.Contains(location))
                    {
                        areas.Add("a shop");
                    }
                    else
                    {
                        areas.Add(LogicManager.GetItemDef(location).areaName.Replace('_', ' '));
                    }
                }
                hint = "Oh, hello there! Seems we both tread far from the path." +
                       "<page>" + "I can hardly believe those dusty old highways led to such a lush and lively place!" +
                       "<page>" + "This building suggests some form of worship, though its idol has clearly been long forgotten. Doubles equally well for a moment's respite."
                       + "<page>" + "Oh, I picked up a good tip for you too. If you're looking to get to higher places, try checking " + areas[0] + "."
                       + "<page>" + "You should be able to find something useful there.";
                break;

            case "QUIRREL_QUEENSTATION_01":
                locations.Add(RandomizerMod.Instance.Settings.ItemPlacements.First(pair => pair.Item1 == "Mothwing_Cloak" || pair.Item1 == "Shade_Cloak").Item2);
                foreach (string location in locations)
                {
                    if (LogicManager.ShopNames.Contains(location))
                    {
                        areas.Add("a shop");
                    }
                    else
                    {
                        areas.Add(LogicManager.GetItemDef(location).areaName.Replace('_', ' '));
                    }
                }
                hint = "Isn't this something. I'd not expected to discover so huge a Stag Station after that foggy descent." +
                       "<page>" + "The bugs of Hallownest must've been an impressive lot, building such grand structures so far into these wilds." +
                       "<page>" + "Seems the dangerous creatures about haven't yet made their way in here. It's the perfect place for a quick rest." +
                       "<page>" + "From this point on, you're going to need to move a bit faster. I've heard tell of a special cloak that confers such a power." +
                       "<page>" + "I couldn't find it myself, but you might. Try looking in " + areas[0] + ".";
                break;

            case "QUIRREL_MANTIS_01":
                locations.Add(RandomizerMod.Instance.Settings.ItemPlacements.First(pair => pair.Item1 == "Lumafly_Lantern").Item2);
                foreach (string location in locations)
                {
                    if (LogicManager.ShopNames.Contains(location))
                    {
                        areas.Add("a shop");
                    }
                    else
                    {
                        areas.Add(LogicManager.GetItemDef(location).areaName.Replace('_', ' '));
                    }
                }
                hint = "Hello again! I suppose you've already met with the tribe of this village, hmm? They seem a little distrustful of strangers... to put it lightly." +
                       "<page>" + "They're not brutes though, no. The sickness in the air that clouds the mind of lesser beasts... they resist it. They retain their intellect and their honour, though also their lethal traditions." +
                       "<page>" + "I've some words of advice, my friend. If you plan to head down below, past the lords of this village, you'll find it far more difficult without a tool to light your way." +
                       "<page>" + "I saw an extra one while I was passing through " + areas[0] + ".";
                break;

            case "QUIRREL_RUINS_1":
                locations = RandomizerMod.Instance.Settings.ItemPlacements.Where(pair => new List <string> {
                    "Desolate_Dive", "Descending_Dark"
                }.Contains(pair.Item1)).Select(pair => pair.Item2).ToList();
                foreach (string location in locations)
                {
                    if (LogicManager.ShopNames.Contains(location))
                    {
                        areas.Add("a shop");
                    }
                    else
                    {
                        areas.Add(LogicManager.GetItemDef(location).areaName.Replace('_', ' '));
                    }
                }
                hint = "The capital lies before us my friend. What a sombre place it seems and one that holds the answers to many a mystery." +
                       "<page>" + "I too have felt the pull of this place, though now I sit before it I find myself hesitant to descend." +
                       "<page>" + "Is it fear I wonder, or something else that holds me back?" +
                       "<page>" + "The stories of the terrible research done in the sanctum before us are too terrible to repeat. Supposedly they developed a spell to smash through the ground, but the art was lost when the city fell." +
                       "<page>" + "If you need that kind of power, try searching " + areas[0] + ". That seems like the most likely place to find it. You might also find it in " + areas[1] + " but that will take some digging.";
                break;

            case "QUIRREL_SPA":
                locations.Add(RandomizerMod.Instance.Settings.ItemPlacements.Last(pair => pair.Item1 == "Mothwing_Cloak" || pair.Item1 == "Shade_Cloak").Item2);
                foreach (string location in locations)
                {
                    if (LogicManager.ShopNames.Contains(location))
                    {
                        areas.Add("a shop");
                    }
                    else
                    {
                        areas.Add(LogicManager.GetItemDef(location).areaName.Replace('_', ' '));
                    }
                }
                hint = "Hello, hello! What a thrill this is, to find such warm comfort amidst the den of beasts." +
                       "<page>" + "This is a ferocious place no doubt. Supposedly, there's a village deep in the warren. Its inhabitants never accepted Hallownest's King." +
                       "<page>" + "By the way, have you noticed those strange black barriers strewn about?" +
                       "<page>" + "Supposedly the tool to get past them was sealed away in " + areas[0] + ", but who can say for sure?";
                break;

            case "QUIRREL_MINES_2":
                locations.Add(RandomizerMod.Instance.Settings.ItemPlacements.Last(pair => pair.Item1 == "Crystal_Heart").Item2);
                foreach (string location in locations)
                {
                    if (LogicManager.ShopNames.Contains(location))
                    {
                        areas.Add("a shop");
                    }
                    else
                    {
                        areas.Add(LogicManager.GetItemDef(location).areaName.Replace('_', ' '));
                    }
                }
                hint = "Did it sadden you to see those miners below, still labouring at their endless task?" +
                       "<page>" + "Even overcome, strong purpose has been imprinted upon their husks." +
                       "<page>" + "The crystal ore is said to contain a sort of energy, not as powerful as the soul the city dwellers harnessed but far less lethal." +
                       "<page>" + "Now, the cores they use to power their tunneling machines must've had incredible power, but not many remain. The only one I know of was moved to " + areas[0] + ".";
                break;

            case "QUIRREL_FOGCANYON_A":
                locations.Add(RandomizerMod.Instance.Settings.ItemPlacements.Last(pair => pair.Item1 == "Isma's_Tear").Item2);
                foreach (string location in locations)
                {
                    if (LogicManager.ShopNames.Contains(location))
                    {
                        areas.Add("a shop");
                    }
                    else
                    {
                        areas.Add(LogicManager.GetItemDef(location).areaName.Replace('_', ' '));
                    }
                }
                hint = "Doesn't this kingdom just abound with surprises? A building atop an acid lake." +
                       "<page>" + "Speaking of, I'm impressed you were able to make it this far. The acid is quite threatening to our kind, without the proper protection." +
                       "<page>" + "If you still need that ability, I'd suggest searching around " + areas[0] +
                       "<page>" + "Despite the sight, I can't help but feel... familiarity? Something stirs in my mind, though I can't yet tell what.." +
                       "<page>" + "I'd thought it my lust for discovery that led me here but now there seems something else." +
                       "<page>" + "This building beckons me.";
                break;

            case "QUIRREL_EPILOGUE_A":
                locations.Add(RandomizerMod.Instance.Settings.ItemPlacements.First(pair => pair.Item1 == "Mantis_Claw" || pair.Item1 == "Monarch_Wings").Item2);
                foreach (string location in locations)
                {
                    if (LogicManager.ShopNames.Contains(location))
                    {
                        areas.Add("a shop");
                    }
                    else
                    {
                        areas.Add(LogicManager.GetItemDef(location).areaName.Replace('_', ' '));
                    }
                }
                hint = "Again we meet, my short friend. Here at last, I feel at peace." +
                       "<page>" + "I suppose your quest is still far from over though. If you still seek greater heights, go to " + areas[0] + ". You should find it there, I hope..." +
                       "<page>" + "Twice I've seen this world and though my service may have stripped the first experience from me, I'm thankful I could witness its beauty again." +
                       "<page>" + "Hallownest is a vast and wondrous thing, but with as many wonders as it holds, I've seen none quite so intriguing as you." +
                       "<page>" + "Ha. My flattery returns only silent stoicism. I like that." +
                       "<page>" + "I like that very much.";
                break;

            default:
                LogWarn("Unknown key passed to GetQuirrelHint");
                break;
            }
            if (hint == string.Empty)
            {
                return(Language.Language.GetInternal(key, sheetTitle));
            }

            RandoLogger.LogHintToTracker(hint, jiji: false, quirrel: true);
            return(hint);
        }
Exemple #6
0
        public static void StartDataChanges()
        {
            PlayerData.instance.Reset();

            PlayerData.instance.hasCharm = true;

            /*
             * if (RandomizerMod.Instance.Settings.FreeLantern)
             * {
             *  PlayerData.instance.hasLantern = true;
             * }
             */

            if (RandomizerMod.Instance.Settings.EarlyGeo)
            {
                // added version checking to the early geo randomization
                int geoSeed = RandomizerMod.Instance.Settings.Seed;
                unchecked
                {
                    geoSeed = geoSeed * 17 + 31 * RandomizerMod.Instance.MakeAssemblyHash();
                }

                // added settings checking to early geo randomization
                // split away difficulty settings etc from randomization settings so we have a bit more room
                int randomizationSettingsSeed = 0;
                if (RandomizerMod.Instance.Settings.RandomizeDreamers)
                {
                    randomizationSettingsSeed += 1;
                }
                randomizationSettingsSeed = randomizationSettingsSeed << 1;
                if (RandomizerMod.Instance.Settings.RandomizeSkills)
                {
                    randomizationSettingsSeed += 1;
                }
                randomizationSettingsSeed = randomizationSettingsSeed << 1;
                if (RandomizerMod.Instance.Settings.RandomizeCharms)
                {
                    randomizationSettingsSeed += 1;
                }
                randomizationSettingsSeed = randomizationSettingsSeed << 1;
                if (RandomizerMod.Instance.Settings.RandomizeKeys)
                {
                    randomizationSettingsSeed += 1;
                }
                randomizationSettingsSeed = randomizationSettingsSeed << 1;
                if (RandomizerMod.Instance.Settings.RandomizeGeoChests)
                {
                    randomizationSettingsSeed += 1;
                }
                randomizationSettingsSeed = randomizationSettingsSeed << 1;
                if (RandomizerMod.Instance.Settings.RandomizeMaskShards)
                {
                    randomizationSettingsSeed += 1;
                }
                randomizationSettingsSeed = randomizationSettingsSeed << 1;
                if (RandomizerMod.Instance.Settings.RandomizeVesselFragments)
                {
                    randomizationSettingsSeed += 1;
                }
                randomizationSettingsSeed = randomizationSettingsSeed << 1;
                if (RandomizerMod.Instance.Settings.RandomizeCharmNotches)
                {
                    randomizationSettingsSeed += 1;
                }
                randomizationSettingsSeed = randomizationSettingsSeed << 1;
                if (RandomizerMod.Instance.Settings.RandomizePaleOre)
                {
                    randomizationSettingsSeed += 1;
                }
                randomizationSettingsSeed = randomizationSettingsSeed << 1;
                if (RandomizerMod.Instance.Settings.RandomizeRancidEggs)
                {
                    randomizationSettingsSeed += 1;
                }
                randomizationSettingsSeed = randomizationSettingsSeed << 1;
                if (RandomizerMod.Instance.Settings.RandomizeRelics)
                {
                    randomizationSettingsSeed += 1;
                }
                randomizationSettingsSeed = randomizationSettingsSeed << 1;
                if (RandomizerMod.Instance.Settings.RandomizeMaps)
                {
                    randomizationSettingsSeed += 1;
                }
                randomizationSettingsSeed = randomizationSettingsSeed << 1;
                if (RandomizerMod.Instance.Settings.RandomizeStags)
                {
                    randomizationSettingsSeed += 1;
                }
                randomizationSettingsSeed = randomizationSettingsSeed << 1;
                if (RandomizerMod.Instance.Settings.RandomizeGrubs)
                {
                    randomizationSettingsSeed += 1;
                }
                randomizationSettingsSeed = randomizationSettingsSeed << 1;
                if (RandomizerMod.Instance.Settings.RandomizeWhisperingRoots)
                {
                    randomizationSettingsSeed += 1;
                }
                randomizationSettingsSeed = randomizationSettingsSeed << 1;
                if (RandomizerMod.Instance.Settings.RandomizeRocks)
                {
                    randomizationSettingsSeed += 1;
                }
                randomizationSettingsSeed = randomizationSettingsSeed << 1;
                if (RandomizerMod.Instance.Settings.RandomizeSoulTotems)
                {
                    randomizationSettingsSeed += 1;
                }
                randomizationSettingsSeed = randomizationSettingsSeed << 1;
                if (RandomizerMod.Instance.Settings.RandomizeLoreTablets)
                {
                    randomizationSettingsSeed += 1;
                }
                randomizationSettingsSeed = randomizationSettingsSeed << 1;
                if (RandomizerMod.Instance.Settings.RandomizeLifebloodCocoons)
                {
                    randomizationSettingsSeed += 1;
                }
                randomizationSettingsSeed = randomizationSettingsSeed << 1;
                if (RandomizerMod.Instance.Settings.RandomizeGrimmkinFlames)
                {
                    randomizationSettingsSeed += 1;
                }
                randomizationSettingsSeed = randomizationSettingsSeed << 1;
                if (RandomizerMod.Instance.Settings.RandomizeBossEssence)
                {
                    randomizationSettingsSeed += 1;
                }
                randomizationSettingsSeed = randomizationSettingsSeed << 1;
                if (RandomizerMod.Instance.Settings.RandomizeBossGeo)
                {
                    randomizationSettingsSeed += 1;
                }
                randomizationSettingsSeed <<= 1;
                if (RandomizerMod.Instance.Settings.EggShop)
                {
                    randomizationSettingsSeed += 1;
                }
                randomizationSettingsSeed <<= 1;
                if (RandomizerMod.Instance.Settings.RandomizeJunkPitChests)
                {
                    randomizationSettingsSeed += 1;
                }
                randomizationSettingsSeed <<= 1;
                if (RandomizerMod.Instance.Settings.RandomizeJournalEntries)
                {
                    randomizationSettingsSeed += 1;
                }
                randomizationSettingsSeed = randomizationSettingsSeed << 1;
                if (RandomizerMod.Instance.Settings.RandomizePalaceTotems ||
                    RandomizerMod.Instance.Settings.RandomizePalaceTablets ||
                    RandomizerMod.Instance.Settings.RandomizePalaceEntries)
                {
                    randomizationSettingsSeed += 1;
                }

                int miscSettingsSeed = 0;
                if (RandomizerMod.Instance.Settings.DuplicateMajorItems)
                {
                    miscSettingsSeed += 1;
                }
                miscSettingsSeed = miscSettingsSeed << 1;
                if (RandomizerMod.Instance.Settings.ShadeSkips)
                {
                    miscSettingsSeed += 1;
                }
                miscSettingsSeed = miscSettingsSeed << 1;
                if (RandomizerMod.Instance.Settings.AcidSkips)
                {
                    miscSettingsSeed += 1;
                }
                miscSettingsSeed = miscSettingsSeed << 1;
                if (RandomizerMod.Instance.Settings.SpikeTunnels)
                {
                    miscSettingsSeed += 1;
                }
                miscSettingsSeed = miscSettingsSeed << 1;
                if (RandomizerMod.Instance.Settings.MildSkips)
                {
                    miscSettingsSeed += 1;
                }
                miscSettingsSeed = miscSettingsSeed << 1;
                if (RandomizerMod.Instance.Settings.SpicySkips)
                {
                    miscSettingsSeed += 1;
                }
                miscSettingsSeed = miscSettingsSeed << 1;
                if (RandomizerMod.Instance.Settings.FireballSkips)
                {
                    miscSettingsSeed += 1;
                }
                miscSettingsSeed = miscSettingsSeed << 1;
                if (RandomizerMod.Instance.Settings.DarkRooms)
                {
                    miscSettingsSeed += 1;
                }
                miscSettingsSeed = miscSettingsSeed << 1;
                if (RandomizerMod.Instance.Settings.RandomizeClawPieces)
                {
                    miscSettingsSeed += 1;
                }
                miscSettingsSeed <<= 1;
                if (RandomizerMod.Instance.Settings.RandomizeCloakPieces)
                {
                    miscSettingsSeed += 1;
                }
                miscSettingsSeed <<= 1;
                if (RandomizerMod.Instance.Settings.CursedNail)
                {
                    miscSettingsSeed += 1;
                }
                miscSettingsSeed <<= 1;
                if (RandomizerMod.Instance.Settings.RandomizeRooms)
                {
                    miscSettingsSeed += 1;
                }
                miscSettingsSeed <<= 1;
                if (RandomizerMod.Instance.Settings.RandomizeAreas || RandomizerMod.Instance.Settings.ConnectAreas)
                {
                    miscSettingsSeed += 1;
                }
                miscSettingsSeed <<= 1;
                if (RandomizerMod.Instance.Settings.CursedMasks)
                {
                    miscSettingsSeed += 1;
                }
                miscSettingsSeed <<= 1;
                if (RandomizerMod.Instance.Settings.CursedNotches)
                {
                    miscSettingsSeed += 1;
                }
                miscSettingsSeed <<= 1;
                if (RandomizerMod.Instance.Settings.RandomizeSwim)
                {
                    miscSettingsSeed += 1;
                }
                miscSettingsSeed <<= 1;
                if (RandomizerMod.Instance.Settings.RandomizeNotchCosts)
                {
                    miscSettingsSeed += 1;
                }
                miscSettingsSeed <<= 1;
                if (RandomizerMod.Instance.Settings.ElevatorPass)
                {
                    miscSettingsSeed += 1;
                }

                int settingsSeed = 0;
                unchecked
                {
                    settingsSeed = 59 * randomizationSettingsSeed + 97 * miscSettingsSeed;
                }

                Random rand     = new Random(geoSeed + settingsSeed);
                int    startgeo = rand.Next(300, 600);
                PlayerData.instance.AddGeo(startgeo);
            }

            Ref.PD.unchainedHollowKnight     = true;
            Ref.PD.encounteredMimicSpider    = true;
            Ref.PD.infectedKnightEncountered = true;
            Ref.PD.mageLordEncountered       = true;
            Ref.PD.mageLordEncountered_2     = true;
            Ref.PD.godseekerUnlocked         = true;

            if (RandomizerMod.Instance.Settings.EggShop)
            {
                Ref.PD.jijiMet = true;
            }
            if (RandomizerMod.Instance.Settings.ElevatorPass)
            {
                Ref.PD.SetBool(nameof(PlayerData.cityLift2), false);
            }

            List <string> startItems = RandomizerMod.Instance.Settings.ItemPlacements.Where(pair => pair.Item2.StartsWith("Equip")).Select(pair => pair.Item1).ToList();

            foreach (string item in startItems)
            {
                GiveAction action = LogicManager.GetItemDef(item).action;
                if (action == GiveAction.Charm)
                {
                    action = GiveAction.EquippedCharm;
                }
                else if (action == GiveAction.SpawnGeo)
                {
                    action = GiveAction.AddGeo;
                }

                GiveItem(action, item, "Equipped");
            }

            if (RandomizerMod.Instance.Settings.CursedNotches)
            {
                PlayerData.instance.charmSlots = 1;
            }

            if (RandomizerMod.Instance.Settings.CursedMasks)
            {
                PlayerData.instance.maxHealth     = 1;
                PlayerData.instance.maxHealthBase = 1;
            }

            if (RandomizerMod.Instance.Settings.RandomizeNotchCosts)
            {
                Random rng      = new Random(RandomizerMod.Instance.Settings.Seed + 1111);
                int[]  costs    = new int[40];
                int    minTotal = 60;
                int    maxTotal = 120;

                for (int total = rng.Next(minTotal, maxTotal); total > 0; total--)
                {
                    int i = rng.Next(40);
                    while (costs[i] >= 6)
                    {
                        i = rng.Next(40);
                    }
                    costs[i]++;
                }

                // clamp dashmaster/sprintmaster for logic purposes
                if (!RandomizerMod.Instance.Settings.CursedNotches && costs[30] > 2 && costs[36] > 2)
                {
                    int d;
                    if (rng.Next(2) == 0)
                    {
                        d = 30;
                    }
                    else
                    {
                        d = 36;
                    }

                    while (costs[d] > 2)
                    {
                        int e = rng.Next(40);
                        while (costs[e] >= 6)
                        {
                            e = rng.Next(40);
                        }
                        costs[d]--;
                        costs[e]++;
                    }
                }

                StringBuilder sb = new StringBuilder();
                sb.AppendLine();
                sb.AppendLine("Randomized Notch Costs");
                Dictionary <int, string> charmNums = LogicManager.ItemNames.Select(i => (i, LogicManager.GetItemDef(i)))
                                                     .Where(p => p.Item2.pool == "Charm" && IsValidCharmNum(p.Item2.charmNum))
                                                     .ToDictionary(p => p.Item2.charmNum, p => p.i);
                charmNums[36] = "Kingsoul";
                charmNums[40] = "Grimmchild";

                int count = 0;
                for (int i = 0; i < 40; i++)
                {
                    count += costs[i];
                    PlayerData.instance.SetInt($"charmCost_{i + 1}", costs[i]);
                    if (charmNums.TryGetValue(i + 1, out string name))
                    {
                        sb.AppendLine($"{name}: {costs[i]}".Replace('_', ' '));
                    }
                    else
                    {
                        sb.AppendLine($"Unknown charm with id {i + 1}: {costs[i]}");
                    }
                }
                sb.AppendLine($"Total: {count}, within the allowed range of [{minTotal}, {maxTotal}].");
                sb.AppendLine($"This is {Mathf.Round(count / 90f * 100)}% of the vanilla total.");
                RandoLogger.LogSpoiler(sb.ToString());
            }

            PlayerData.instance.CalculateNotchesUsed();

            for (int i = 1; i < 5; i++)
            {
                if (PlayerData.instance.charmSlotsFilled > PlayerData.instance.charmSlots)
                {
                    PlayerData.instance.charmSlots++;
                    PlayerData.instance.SetBool("salubraNotch" + i, true);
                }
                if (PlayerData.instance.charmSlotsFilled <= PlayerData.instance.charmSlots)
                {
                    PlayerData.instance.overcharmed = false;
                    break;
                }
            }

            PlayerData.instance.respawnScene      = start.sceneName;
            PlayerData.instance.respawnMarkerName = RESPAWN_MARKER_NAME;
            PlayerData.instance.respawnType       = 0;
            PlayerData.instance.mapZone           = start.zone;
        }