/* Autosplitter for What Lies in the Multiverse v1.4.0 Supports versions 1.0.23 - 1.1.7 */ state("What Lies in the Multiverse") { } state("What Lies in the Multiverse", "1.1.7") { int room_id: "What Lies in the Multiverse.exe", 0x2D4B780; double totalGameTime: "What Lies in the Multiverse.exe", 0x2F8298C, 0x68, 0x130, 0x490; double prologueTime: "What Lies in the Multiverse.exe", 0x2F8298C, 0x68, 0xD4, 0x0, 0xD00; double chapter1Time: "What Lies in the Multiverse.exe", 0x2F8298C, 0x68, 0xD4, 0x0, 0xD10; double chapter2Time: "What Lies in the Multiverse.exe", 0x2F8298C, 0x68, 0xD4, 0x0, 0xD20; double chapter3Time: "What Lies in the Multiverse.exe", 0x2F8298C, 0x68, 0xD4, 0x0, 0xD30; double chapter4Time: "What Lies in the Multiverse.exe", 0x2F8298C, 0x68, 0xD4, 0x0, 0xD40; double chapter5Time: "What Lies in the Multiverse.exe", 0x2F8298C, 0x68, 0xD4, 0x0, 0xD50; double chapter6Time: "What Lies in the Multiverse.exe", 0x2F8298C, 0x68, 0xD4, 0x0, 0xD60; double chapter7Time: "What Lies in the Multiverse.exe", 0x2F8298C, 0x68, 0xD4, 0x0, 0xD70; double chapter8Time: "What Lies in the Multiverse.exe", 0x2F8298C, 0x68, 0xD4, 0x0, 0xD80; double chapter9Time: "What Lies in the Multiverse.exe", 0x2F8298C, 0x68, 0xD4, 0x0, 0xD90; } state("What Lies in the Multiverse", "1.1.6") { int room_id: "What Lies in the Multiverse.exe", 0x722248; double totalGameTime: "What Lies in the Multiverse.exe", 0x739278, 0x68, 0x154, 0x4B0; double prologueTime: "What Lies in the Multiverse.exe", 0x739278, 0x68, 0x154, 0x0, 0xD00; double chapter1Time: "What Lies in the Multiverse.exe", 0x739278, 0x68, 0x154, 0x0, 0xD10; double chapter2Time: "What Lies in the Multiverse.exe", 0x739278, 0x68, 0x154, 0x0, 0xD20; double chapter3Time: "What Lies in the Multiverse.exe", 0x739278, 0x68, 0x154, 0x0, 0xD30; double chapter4Time: "What Lies in the Multiverse.exe", 0x739278, 0x68, 0x154, 0x0, 0xD40; double chapter5Time: "What Lies in the Multiverse.exe", 0x739278, 0x68, 0x154, 0x0, 0xD50; double chapter6Time: "What Lies in the Multiverse.exe", 0x739278, 0x68, 0x154, 0x0, 0xD60; double chapter7Time: "What Lies in the Multiverse.exe", 0x739278, 0x68, 0x154, 0x0, 0xD70; double chapter8Time: "What Lies in the Multiverse.exe", 0x739278, 0x68, 0x154, 0x0, 0xD80; double chapter9Time: "What Lies in the Multiverse.exe", 0x739278, 0x68, 0x154, 0x0, 0xD90; } state("What Lies in the Multiverse", "1.1.2") { int room_id: "What Lies in the Multiverse.exe", 0x2D456A0; double totalGameTime: "What Lies in the Multiverse.exe", 0x2F7C8AC, 0x68, 0x130, 0x490; double prologueTime: "What Lies in the Multiverse.exe", 0x2F7C8AC, 0x68, 0xD4, 0x0, 0xD00; double chapter1Time: "What Lies in the Multiverse.exe", 0x2F7C8AC, 0x68, 0xD4, 0x0, 0xD10; double chapter2Time: "What Lies in the Multiverse.exe", 0x2F7C8AC, 0x68, 0xD4, 0x0, 0xD20; double chapter3Time: "What Lies in the Multiverse.exe", 0x2F7C8AC, 0x68, 0xD4, 0x0, 0xD30; double chapter4Time: "What Lies in the Multiverse.exe", 0x2F7C8AC, 0x68, 0xD4, 0x0, 0xD40; double chapter5Time: "What Lies in the Multiverse.exe", 0x2F7C8AC, 0x68, 0xD4, 0x0, 0xD50; double chapter6Time: "What Lies in the Multiverse.exe", 0x2F7C8AC, 0x68, 0xD4, 0x0, 0xD60; double chapter7Time: "What Lies in the Multiverse.exe", 0x2F7C8AC, 0x68, 0xD4, 0x0, 0xD70; double chapter8Time: "What Lies in the Multiverse.exe", 0x2F7C8AC, 0x68, 0xD4, 0x0, 0xD80; double chapter9Time: "What Lies in the Multiverse.exe", 0x2F7C8AC, 0x68, 0xD4, 0x0, 0xD90; } state("What Lies in the Multiverse", "1.1.1") { int room_id: "What Lies in the Multiverse.exe", 0x2D3B650; double totalGameTime: "What Lies in the Multiverse.exe", 0x2F7285C, 0x68, 0x130, 0x490; double prologueTime: "What Lies in the Multiverse.exe", 0x2F7285C, 0x68, 0xD4, 0x0, 0xD00; double chapter1Time: "What Lies in the Multiverse.exe", 0x2F7285C, 0x68, 0xD4, 0x0, 0xD10; double chapter2Time: "What Lies in the Multiverse.exe", 0x2F7285C, 0x68, 0xD4, 0x0, 0xD20; double chapter3Time: "What Lies in the Multiverse.exe", 0x2F7285C, 0x68, 0xD4, 0x0, 0xD30; double chapter4Time: "What Lies in the Multiverse.exe", 0x2F7285C, 0x68, 0xD4, 0x0, 0xD40; double chapter5Time: "What Lies in the Multiverse.exe", 0x2F7285C, 0x68, 0xD4, 0x0, 0xD50; double chapter6Time: "What Lies in the Multiverse.exe", 0x2F7285C, 0x68, 0xD4, 0x0, 0xD60; double chapter7Time: "What Lies in the Multiverse.exe", 0x2F7285C, 0x68, 0xD4, 0x0, 0xD70; double chapter8Time: "What Lies in the Multiverse.exe", 0x2F7285C, 0x68, 0xD4, 0x0, 0xD80; double chapter9Time: "What Lies in the Multiverse.exe", 0x2F7285C, 0x68, 0xD4, 0x0, 0xD90; } state("What Lies in the Multiverse", "1.0.47") { int room_id: "What Lies in the Multiverse.exe", 0x2D2C2E0; double totalGameTime: "What Lies in the Multiverse.exe", 0x2F634EC, 0x68, 0x130, 0x490; double prologueTime: "What Lies in the Multiverse.exe", 0x2F634EC, 0x68, 0xC8, 0x0, 0xD00; double chapter1Time: "What Lies in the Multiverse.exe", 0x2F634EC, 0x68, 0xC8, 0x0, 0xD10; double chapter2Time: "What Lies in the Multiverse.exe", 0x2F634EC, 0x68, 0xC8, 0x0, 0xD20; double chapter3Time: "What Lies in the Multiverse.exe", 0x2F634EC, 0x68, 0xC8, 0x0, 0xD30; double chapter4Time: "What Lies in the Multiverse.exe", 0x2F634EC, 0x68, 0xC8, 0x0, 0xD40; double chapter5Time: "What Lies in the Multiverse.exe", 0x2F634EC, 0x68, 0xC8, 0x0, 0xD50; double chapter6Time: "What Lies in the Multiverse.exe", 0x2F634EC, 0x68, 0xC8, 0x0, 0xD60; double chapter7Time: "What Lies in the Multiverse.exe", 0x2F634EC, 0x68, 0xC8, 0x0, 0xD70; double chapter8Time: "What Lies in the Multiverse.exe", 0x2F634EC, 0x68, 0xC8, 0x0, 0xD80; double chapter9Time: "What Lies in the Multiverse.exe", 0x2F634EC, 0x68, 0xC8, 0x0, 0xD90; } state("What Lies in the Multiverse", "1.0.23") { int room_id: "What Lies in the Multiverse.exe", 0x2C646F0; } startup { vars.Log = (Action)(value => print(String.Concat("[What Lies in the Multiverse] ", value))); settings.Add("BuiltInTimer", true, "Use game's built-in timer for IGT (v1.0.47+)"); settings.Add("ChapterSelect", false, "Chapter Select Mode"); settings.Add("Splits", true, "Split at the start of..."); settings.Add("chapter0", true, "Prologue", "Splits"); settings.Add("chapter1", true, "Chapter 1", "Splits"); settings.Add("chapter2", true, "Chapter 2", "Splits"); settings.Add("chapter3", true, "Chapter 3", "Splits"); settings.Add("chapter4", true, "Chapter 4", "Splits"); settings.Add("chapter5", true, "Chapter 5", "Splits"); settings.Add("chapter6", true, "Chapter 6", "Splits"); settings.Add("chapter7", true, "Chapter 7", "Splits"); settings.Add("chapter8", true, "Chapter 8", "Splits"); settings.Add("chapter9", true, "Final Chapter", "Splits"); settings.Add("chapter10", true, "Credits", "Splits"); if (timer.CurrentTimingMethod == TimingMethod.RealTime) { var messageBox = MessageBox.Show( "The game is run in IGT (Time without Loads - Game Time).\n"+ "LiveSplit is currently set to show Real Time (RTA).\n"+ "Would you like to set the timing method to Game Time?", "LiveSplit | What Lies in the Multiverse", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (messageBox == DialogResult.Yes) timer.CurrentTimingMethod = TimingMethod.GameTime; } } init { byte[] exeMD5HashBytes = new byte[0]; using (var md5 = System.Security.Cryptography.MD5.Create()) { using (var s = File.Open(modules.First().FileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { exeMD5HashBytes = md5.ComputeHash(s); } } var md5hash = exeMD5HashBytes.Select(x => x.ToString("X2")).Aggregate((a, b) => a + b); print("MD5: " + md5hash); switch(md5hash) { case "82CC30B74E4CDE4136CEBAD23167E1DB": version = "1.1.7"; break; case "5F82C7083BF6E27AA9993CDDDBB0C985": version = "1.1.6"; break; case "1FFC005CA71C11348DE241390A9E390D": version = "1.1.2"; break; case "F7E6C5C93D2ED4A2CEE65B76F8DAFE0A": version = "1.1.1"; break; case "3453B3FCFC38E40692C48BFE9DE5EE2B": version = "1.0.47"; break; case "67DD43B40FE03B4BD636DB065106B0B6": version = "1.0.23"; break; } // Special Room IDs vars.titleScreen = 62; vars.leosOffice = 74; vars.theFirstInterference = 28; // Init Chapter Time variable for Chapter Select Mode vars.chapterTimes = new double[11]; vars.totalChapterTime = (double)0; switch(version) { case "1.1.7": vars.chapterFirstRooms = new int[11] { 241, 249, 77, 57, 56, 206, 79, 208, 46, 19, 91 }; break; case "1.1.6": case "1.1.2": case "1.1.1": case "1.0.47": vars.chapterFirstRooms = new int[11] { 239, 247, 77, 57, 56, 204, 79, 206, 46, 19, 91 }; break; case "1.0.23": vars.chapterFirstRooms = new int[11] { 237, 245, 77, 57, 56, 202, 79, 204, 46, 19, 91 }; break; } } update { if (current.room_id != old.room_id) vars.Log("Room ID changed from " + old.room_id.ToString() + " to " + current.room_id.ToString()); for (var i = 0; i < vars.chapterFirstRooms.Length; i++) { if (current.room_id == vars.chapterFirstRooms[i]) current.chapter = i; } if (version != "1.0.23") { if (settings["ChapterSelect"]) { if (current.room_id != vars.titleScreen) { if (current.chapter == 0 && current.prologueTime > vars.chapterTimes[0]) vars.chapterTimes[0] = current.prologueTime; if (current.chapter == 1 && current.chapter1Time > vars.chapterTimes[1]) vars.chapterTimes[1] = current.chapter1Time; if (current.chapter == 2 && current.chapter2Time > vars.chapterTimes[2]) vars.chapterTimes[2] = current.chapter2Time; if (current.chapter == 3 && current.chapter3Time > vars.chapterTimes[3]) vars.chapterTimes[3] = current.chapter3Time; if (current.chapter == 4 && current.chapter4Time > vars.chapterTimes[4]) vars.chapterTimes[4] = current.chapter4Time; if (current.chapter == 5 && current.chapter5Time > vars.chapterTimes[5]) vars.chapterTimes[5] = current.chapter5Time; if (current.chapter == 6 && current.chapter6Time > vars.chapterTimes[6]) vars.chapterTimes[6] = current.chapter6Time; if (current.chapter == 7 && current.chapter7Time > vars.chapterTimes[7]) vars.chapterTimes[7] = current.chapter7Time; if (current.chapter == 8 && current.chapter8Time > vars.chapterTimes[8]) vars.chapterTimes[8] = current.chapter8Time; if (current.chapter == 9 && current.chapter9Time > vars.chapterTimes[9]) vars.chapterTimes[9] = current.chapter9Time; } vars.totalChapterTime = 0; for (var i = 0; i < 10; i++) vars.totalChapterTime += vars.chapterTimes[i]; // Variables populated for optional use with the ASLVarViewer component vars.PrologueTime = TimeSpan.FromSeconds(vars.chapterTimes[0] / 60).ToString(@"hh\:mm\:ss\.ff"); vars.Chapter1Time = TimeSpan.FromSeconds(vars.chapterTimes[1] / 60).ToString(@"hh\:mm\:ss\.ff"); vars.Chapter2Time = TimeSpan.FromSeconds(vars.chapterTimes[2] / 60).ToString(@"hh\:mm\:ss\.ff"); vars.Chapter3Time = TimeSpan.FromSeconds(vars.chapterTimes[3] / 60).ToString(@"hh\:mm\:ss\.ff"); vars.Chapter4Time = TimeSpan.FromSeconds(vars.chapterTimes[4] / 60).ToString(@"hh\:mm\:ss\.ff"); vars.Chapter5Time = TimeSpan.FromSeconds(vars.chapterTimes[5] / 60).ToString(@"hh\:mm\:ss\.ff"); vars.Chapter6Time = TimeSpan.FromSeconds(vars.chapterTimes[6] / 60).ToString(@"hh\:mm\:ss\.ff"); vars.Chapter7Time = TimeSpan.FromSeconds(vars.chapterTimes[7] / 60).ToString(@"hh\:mm\:ss\.ff"); vars.Chapter8Time = TimeSpan.FromSeconds(vars.chapterTimes[8] / 60).ToString(@"hh\:mm\:ss\.ff"); vars.Chapter9Time = TimeSpan.FromSeconds(vars.chapterTimes[9] / 60).ToString(@"hh\:mm\:ss\.ff"); vars.TotalGameTime = TimeSpan.FromSeconds(vars.totalChapterTime / 60).ToString(@"hh\:mm\:ss\.ff"); } else { // Variables populated for optional use with the ASLVarViewer component vars.PrologueTime = TimeSpan.FromSeconds(current.prologueTime / 60).ToString(@"hh\:mm\:ss\.ff"); vars.Chapter1Time = TimeSpan.FromSeconds(current.chapter1Time / 60).ToString(@"hh\:mm\:ss\.ff"); vars.Chapter2Time = TimeSpan.FromSeconds(current.chapter2Time / 60).ToString(@"hh\:mm\:ss\.ff"); vars.Chapter3Time = TimeSpan.FromSeconds(current.chapter3Time / 60).ToString(@"hh\:mm\:ss\.ff"); vars.Chapter4Time = TimeSpan.FromSeconds(current.chapter4Time / 60).ToString(@"hh\:mm\:ss\.ff"); vars.Chapter5Time = TimeSpan.FromSeconds(current.chapter5Time / 60).ToString(@"hh\:mm\:ss\.ff"); vars.Chapter6Time = TimeSpan.FromSeconds(current.chapter6Time / 60).ToString(@"hh\:mm\:ss\.ff"); vars.Chapter7Time = TimeSpan.FromSeconds(current.chapter7Time / 60).ToString(@"hh\:mm\:ss\.ff"); vars.Chapter8Time = TimeSpan.FromSeconds(current.chapter8Time / 60).ToString(@"hh\:mm\:ss\.ff"); vars.Chapter9Time = TimeSpan.FromSeconds(current.chapter9Time / 60).ToString(@"hh\:mm\:ss\.ff"); vars.TotalGameTime = TimeSpan.FromSeconds(current.totalGameTime / 60).ToString(@"hh\:mm\:ss\.ff"); } } } start { return old.room_id == vars.titleScreen && current.room_id != vars.titleScreen; } onStart { vars.Log("Starting"); vars.chapterTimes = new double[11]; // On doing chapter select, c7 starts a room early, causing a silly split if (current.room_id == vars.leosOffice) { current.chapter = 7; current.chapter = 7; } } reset { if (settings["ChapterSelect"]) return false; if (old.room_id == vars.theFirstInterference) return false; return old.room_id != vars.titleScreen && current.room_id == vars.titleScreen; } onReset { vars.Log("Resetting"); current.chapter = -1; } isLoading { if (version != "1.0.23" && settings["BuiltInTimer"]) return true; return (current.room_id == vars.titleScreen); } gameTime { if (version != "1.0.23" && settings["BuiltInTimer"]) { if (settings["ChapterSelect"]) return TimeSpan.FromSeconds(vars.totalChapterTime / 60); return TimeSpan.FromSeconds(current.totalGameTime / 60); } } split { if (current.chapter != old.chapter) { vars.Log("Entering Chapter " + current.chapter.ToString()); return settings["chapter" + current.chapter.ToString()]; } }