Created
October 31, 2025 13:55
-
-
Save wRadion/8c8c29a3d652b5b552df0c5e91d829c4 to your computer and use it in GitHub Desktop.
Little Nightmares III - AutoSplitter & Load Remover
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * AutoSplitter and Load Remover for Little Nightmares III | |
| * v1.0 | |
| * | |
| * by Nikko & wRadion | |
| */ | |
| state("LittleNightmaresIII") | |
| { | |
| float xCoord : 0x0643BB38, 0x120, 0x2D8, 0x130, 0x120; | |
| float yCoord : 0x0643BB38, 0x120, 0x2D8, 0x130, 0x11C; | |
| float zCoord : 0x0643BB38, 0x120, 0x2D8, 0x130, 0x124; | |
| float xCoord2 : 0x0643BB38, 0x120, 0x2E8, 0x290, 0x120; | |
| float yCoord2 : 0x0643BB38, 0x120, 0x2E8, 0x290, 0x11C; | |
| float zCoord2 : 0x0643BB38, 0x120, 0x2E8, 0x290, 0x124; | |
| float levelTime : 0x0643BB38, 0x120, 0x2D8, 0x1A0, 0x3F0, 0x288; | |
| } | |
| startup | |
| { | |
| // Chapter 1 | |
| settings.Add("chap1", true, "Chapter 1: Necropolis"); | |
| settings.Add("chap1_umbrella", true, "Umbrella", "chap1"); | |
| settings.Add("chap1_baby_cutscene", true, "Giant Baby Cutscene", "chap1"); | |
| settings.Add("chap1_end", true, "Entering Mirror (end)", "chap1"); | |
| // Chapter 2 | |
| settings.Add("chap2", true, "Chapter 2: Candy Factory"); | |
| settings.Add("chap2_supervisor_chase", true, "Falling after Supervisor chase", "chap2"); | |
| settings.Add("chap2_lobby_elevator", true, "Lobby Elevator upstairs", "chap2"); | |
| settings.Add("chap2_surveillance_exit", true, "Exit Surveillance", "chap2"); | |
| settings.Add("chap2_end", true, "Entering Mirror (end)", "chap2"); | |
| // Chapter 3 | |
| settings.Add("chap3", true, "Chapter 3: Carnevale"); | |
| settings.Add("chap3_voc_exit", true, "Exit Vault of Curiosities", "chap3"); | |
| settings.Add("chap3_post_cargo_fight", true, "Post Bullies Fight Hatch", "chap3"); | |
| settings.Add("chap3_saw_room", true, "Entering Saw Room", "chap3"); | |
| settings.Add("chap3_coaster_storage", true, "Entering Coaster Storage", "chap3"); | |
| settings.Add("chap3_captured", true, "Captured", "chap3"); | |
| settings.Add("chap3_stage_exit", true, "Exiting stage", "chap3"); | |
| settings.Add("chap3_end", true, "Balloon Detached (end)", "chap3"); | |
| // Chapter 4 | |
| settings.Add("chap4", true, "Chapter 4: The Institute"); | |
| settings.Add("chap4_alone_doll", true, "Magic Doll cutscene", "chap4"); | |
| settings.Add("chap4_psychiatrist", true, "The Psychiatrist face cutscene", "chap4"); | |
| settings.Add("chap4_end", true, "Falling after defeating The Psychiatrist (end)", "chap4"); | |
| } | |
| init | |
| { | |
| /* | |
| CHAPTER 1 | |
| - chap1_umbrella (Labyrinth_ExteriorPathway) | |
| - chap1_baby_cutscene (Labyrinth_BeetleFlight) | |
| - chap1_end (Labyrinth_MirrorRoomTop -> Factory_Hideaway) | |
| CHAPTER 2 | |
| - chap2_supervisor_chase (Factory_BalconyCorridor) | |
| - chap2_lobby_elevator (Factory_LobbyLower_0 / Factory_LobbyUpper) | |
| - chap2_surveillance_exit (Factory_SurveillanceExit) | |
| - chap2_end (Factory_MessHallExit -> VOC_EmptyStorageRoom) | |
| CHAPTER 3 | |
| - chap3_voc_exit (VOC_CarneCorridor) | |
| - chap3_post_cargo_fight (Carnevale_PostCargoFight) | |
| - chap3_saw_room (Carnevale_SawRoom during zipline, entering SawRoom) | |
| - chap3_coaster_storage (Carnevale_CoastersEnd -> Carnevale_CoasterStorage) | |
| - chap3_captured (Carnevale_PracticeStage_PreKin) | |
| - chap3_stage_exit (Carnevale_StageExitLower) | |
| - chap3_end (balloon detached and flying away) | |
| CHAPTER 4 | |
| - chap4_alone_doll (TheCopy_ChildHovel) | |
| - chap4_psychiatrist (TheCopy_EastWingEntryRoom) | |
| - chap4_end (TheCopy_HypnotistFight_02) | |
| */ | |
| vars.completedSplits = new Dictionary<string, bool>(); | |
| /* | |
| Checks used to trigger splits with a previous position check | |
| CHAPTER 1 | |
| - chap1_umbrella (Labyrinth_ExteriorPathway) | |
| CHAPTER 4 | |
| - chap4_alone_doll (TheCopy_ChildHovel) | |
| */ | |
| vars.splitChecks = new Dictionary<string, bool>(); | |
| vars.runStarted = false; | |
| Func<float, float, float, float, float, float, float> GetDistance = (x1, y1, z1, x2, y2, z2) => { | |
| float dx = x2 - x1; | |
| float dy = y2 - y1; | |
| float dz = z2 - z1; | |
| return (float)Math.Sqrt(dx * dx + dy * dy + dz * dz); | |
| }; | |
| vars.GetDistance = GetDistance; | |
| Func<float, float, float, float> GetDistanceToCur = (x, y, z) => vars.GetDistance(current.xCoord, current.yCoord, current.zCoord, x, y, z); | |
| vars.GetDistanceToCur = GetDistanceToCur; | |
| Func<string, bool> IsCompleted = (name) => !settings[name] || (vars.completedSplits.ContainsKey(name) && vars.completedSplits[name]); | |
| vars.IsCompleted = IsCompleted; | |
| Func<string, bool> HasCheck = (name) => vars.splitChecks.ContainsKey(name) && vars.splitChecks[name]; | |
| vars.HasCheck = HasCheck; | |
| } | |
| onStart | |
| { | |
| vars.completedSplits.Clear(); | |
| vars.splitChecks.Clear(); | |
| vars.AllGameTime = 0; | |
| vars.runStarted = true; | |
| vars.startGameTime = current.levelTime; | |
| } | |
| onReset | |
| { | |
| vars.completedSplits.Clear(); | |
| vars.splitChecks.Clear(); | |
| vars.AllGameTime = 0; | |
| vars.runStarted = false; | |
| vars.startGameTime = 0; | |
| } | |
| start | |
| { | |
| if (!vars.runStarted && vars.GetDistanceToCur(-67200f, 2050f, -9050f) <= 500f) | |
| return true; | |
| } | |
| reset | |
| { | |
| if (old.xCoord == 0f && old.yCoord == 0f && old.zCoord == 0f && vars.GetDistanceToCur(-94665f, -23570f, -6650.50f) <= 200f) | |
| return true; | |
| } | |
| split | |
| { | |
| /* CHAPTER 1 */ | |
| if (settings["chap1"] && !vars.IsCompleted("chap1_end")) { | |
| // Split for Umbrella | |
| if (!vars.IsCompleted("chap1_umbrella")) { | |
| if (!vars.HasCheck("chap1_umbrella") && vars.GetDistanceToCur(-31890f, 78f, -5629.5f) <= 150f) | |
| vars.splitChecks["chap1_umbrella"] = true; | |
| if (vars.HasCheck("chap1_umbrella") && current.xCoord <= -32000f && -5632.91f <= current.zCoord && current.zCoord <= -5632.89f) { | |
| vars.completedSplits["chap1_umbrella"] = true; | |
| return true; | |
| } | |
| } | |
| // Split for Baby Cutscene (Nightmare) | |
| if (!vars.IsCompleted("chap1_baby_cutscene")) { | |
| if (vars.GetDistance(old.xCoord, old.yCoord, old.zCoord, current.xCoord, current.yCoord, current.zCoord) > 2500f && vars.GetDistanceToCur(3300.00f, -6245.00f, -9760.67f) <= 100f) { | |
| vars.completedSplits["chap1_baby_cutscene"] = true; | |
| return true; | |
| } | |
| } | |
| // Split for Chapter 1 End (entering mirror) | |
| if (vars.GetDistance(old.xCoord, old.yCoord, old.zCoord, current.xCoord, current.yCoord, current.zCoord) > 212000f && vars.GetDistanceToCur(-136467.50f, 590.00f, 37400.50f) <= 150f) { | |
| vars.completedSplits["chap1_end"] = true; | |
| return true; | |
| } | |
| } | |
| /* CHAPTER 2 */ | |
| if (settings["chap2"] && !vars.IsCompleted("chap2_end")) { | |
| // Split for Supervisor Chase (fall after opening door) | |
| if (!vars.IsCompleted("chap2_supervisor_chase")) { | |
| if (vars.GetDistanceToCur(-115223f, 2300f, 39835f) <= 100f && current.xCoord > -115200.0f) { | |
| vars.completedSplits["chap2_supervisor_chase"] = true; | |
| return true; | |
| } | |
| } | |
| // Split for Lobby Elevator (exit first elevator) | |
| if (!vars.IsCompleted("chap2_lobby_elevator")) { | |
| if (vars.GetDistanceToCur(-89140f, 3500f, 43980f) <= 500f && current.yCoord < 3480f) { | |
| vars.completedSplits["chap2_lobby_elevator"] = true; | |
| return true; | |
| } | |
| } | |
| // Split for Surveillance Exit | |
| if (!vars.IsCompleted("chap2_surveillance_exit")) { | |
| if (vars.GetDistanceToCur(-77900f, 1623f, 43210f) <= 500f && current.xCoord > -77850f) { | |
| vars.completedSplits["chap2_surveillance_exit"] = true; | |
| return true; | |
| } | |
| } | |
| // Split for Chapter 2 End (entering mirror) | |
| if (!vars.IsCompleted("chap2_end")) { | |
| if (vars.GetDistance(old.xCoord, old.yCoord, old.zCoord, current.xCoord, current.yCoord, current.zCoord) > 12000f && vars.GetDistanceToCur(71900.00f, 850.00f, 39864.50f) <= 500f) { | |
| vars.completedSplits["chap2_end"] = true; | |
| return true; | |
| } | |
| } | |
| } | |
| /* CHAPTER 3 */ | |
| if (settings["chap3"] && !vars.IsCompleted("chap3_end")) { | |
| // Split for VaultOfCuriosity Exit (after opening locked door) | |
| if (!vars.IsCompleted("chap3_voc_exit")) { | |
| if (vars.GetDistanceToCur(72772.15f, 164.31f, 46154.96f) <= 200f && current.xCoord < 72700) { | |
| vars.completedSplits["chap3_voc_exit"] = true; | |
| return true; | |
| } | |
| } | |
| // Split for Post Cargo Fight (going into the hatch) | |
| if (!vars.IsCompleted("chap3_post_cargo_fight")) { | |
| if (vars.GetDistanceToCur(76989.89f, 950f, 48800f) <= 500f && current.zCoord <= 49000f) { | |
| vars.completedSplits["chap3_post_cargo_fight"] = true; | |
| return true; | |
| } | |
| } | |
| // Split for entering Saw Room (from zipline or ground w/ caravan skip) | |
| if (!vars.IsCompleted("chap3_saw_room")) { | |
| if (vars.GetDistanceToCur(107000f, 5950f, 49500f) <= 1500f && current.xCoord >= 107050f) { | |
| vars.completedSplits["chap3_saw_room"] = true; | |
| return true; | |
| } | |
| } | |
| // Split for entering Coaster Storage room | |
| if (!vars.IsCompleted("chap3_coaster_storage")) { | |
| if (vars.GetDistanceToCur(126624f, 66130f, 47664f) <= 100f && current.xCoord >= 126700f) { | |
| vars.completedSplits["chap3_coaster_storage"] = true; | |
| return true; | |
| } | |
| } | |
| // Split for after capture cutscene (in practice stage) | |
| if (!vars.IsCompleted("chap3_captured")) { | |
| if (vars.GetDistance(old.xCoord, old.yCoord, old.zCoord, current.xCoord, current.yCoord, current.zCoord) > 25000f && vars.GetDistanceToCur(179300f, 65300f, 64650f) <= 1000f) { | |
| vars.completedSplits["chap3_captured"] = true; | |
| return true; | |
| } | |
| } | |
| // Split for Stage Exit (locked door) | |
| if (!vars.IsCompleted("chap3_stage_exit")) { | |
| if (vars.GetDistanceToCur(194050f, 64958f, 64541f) <= 200f && current.xCoord > 194080f) { | |
| vars.completedSplits["chap3_stage_exit"] = true; | |
| return true; | |
| } | |
| } | |
| // Spit for Chapter 3 ending (balloon detached) | |
| if (!vars.IsCompleted("chap3_end")) { | |
| if (vars.GetDistanceToCur(204750f, 56158f, 67000f) <= 500f && current.zCoord > 67000f) { | |
| vars.completedSplits["chap3_end"] = true; | |
| return true; | |
| } | |
| } | |
| } | |
| if (settings["chap4"] && !vars.IsCompleted("chap4_end")) { | |
| // Split for Alone Doll (time doll) | |
| if (!vars.IsCompleted("chap4_alone_doll")) { | |
| if (!vars.HasCheck("chap4_alone_doll") && vars.GetDistanceToCur(250000f, -34680f, 111694f) <= 200f && current.yCoord == -34680.00000f && current.yCoord2 == -34680.00000f) | |
| vars.splitChecks["chap4_alone_doll"] = true; | |
| if (vars.HasCheck("chap4_alone_doll") && (current.zCoord >= 111848f || current.zCoord2 >= 111848f)) { | |
| vars.completedSplits["chap4_alone_doll"] = true; | |
| return true; | |
| } | |
| } | |
| // Split for The Psychiatrist (face reveal cutscene) | |
| if (!vars.IsCompleted("chap4_psychiatrist")) { | |
| if (vars.GetDistanceToCur(275100f, -24300f, 110287f) <= 200f && (current.xCoord > 275122f || current.xCoord2 > 275122f)) { | |
| vars.completedSplits["chap4_psychiatrist"] = true; | |
| return true; | |
| } | |
| } | |
| // Split for Falling after defeating The Psychiatrist | |
| if (!vars.IsCompleted("chap4_end")) { | |
| if (vars.GetDistanceToCur(308932f, -42182f, 100450f) <= 5000f && current.zCoord < 100000f) { | |
| vars.completedSplits["chap4_end"] = true; | |
| return true; | |
| } | |
| } | |
| } | |
| } | |
| isLoading | |
| { | |
| return true; | |
| } | |
| gameTime | |
| { | |
| if (old.levelTime > current.levelTime) | |
| vars.AllGameTime += old.levelTime; | |
| if (current.levelTime >= 0 && vars.runStarted) | |
| return TimeSpan.FromSeconds(vars.AllGameTime+current.levelTime-vars.startGameTime); | |
| else if (!vars.runStarted) | |
| return TimeSpan.FromSeconds(0); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment