/* * Autosplitter and Load Remover by TDOG20, Jigsaw, Balathruin & WillTreaty */ state("speed", "v1.2") { //ID of current race string30 trackID : "speed.exe", 0x51CFCC, 0x44, 0x4, 0x0; //Used for autostart int selectedMenu : "speed.exe", 0x51BF84; float start : "speed.exe", 0x51BA9C, 0x0, 0x18C; //Used for Game Over Split int gameover : "speed.exe", 0x5C1220, 0x490; float frametime : "speed.exe", 0x51F370, 0x20; //Name of current FMV and NIS string14 fmvName : "speed.exe", 0x51C228, 0x18, 0x68, 0x40, 0x0; string11 nisName : "speed.exe", 0x50CA88, 0xC, 0x10, 0x4; //Describes the loading screen state int loadingScreen1 : "speed.exe", 0x510ED0; int loadingScreen2 : "speed.exe", 0x5112D0; bool restartLoad : "speed.exe", 0x51BEE8; //Displays the current state of the game and also helps with the loadless timer int gamestateID : "speed.exe", 0x51CCB4; //Used for deciding if a race is finished or not int raceState : "speed.exe", 0x50F764; //Used for determining if player is in a chase or race int onChase : "speed.exe", 0x51C398; int onRace : "speed.exe", 0x5B27E8; //Used for determining if player has exited shop or carlot/has started a nmg run int inShop: "speed.exe", 0x51B120, 0x118; //Used for Quick Race Mode stuff int raceStart : "speed.exe", 0x510EB0; int raceCP : "speed.exe", 0x51CFC0, 0x44; float completion : "speed.exe", 0x52ED58, 0x2F8, 0x50; } state("speed", "v1.3") { //ID of current race string30 trackID : "speed.exe", 0x51E00C, 0x48, 0x1C; //Used for autostart int selectedMenu : "speed.exe", 0x51CFC4; //Used for Game Over Split int gameover : "speed.exe", 0x5C2270, 0x490; float frametime : "speed.exe", 0x5203B0, 0x20; //Name of current FMV and NIS string14 fmvName : "speed.exe", 0x51D268, 0x18, 0x68, 0x40, 0x0; string11 nisName : "speed.exe", 0x50DAC8, 0xC, 0x10, 0x4; //Describes the loading screen state int loadingScreen1 : "speed.exe", 0x511F10; int loadingScreen2 : "speed.exe", 0x512310; bool restartLoad : "speed.exe", 0x51CF28; //Displays the current state of the game and also helps with the loadless timer int gamestateID : "speed.exe", 0x51DCF4; //Used for deciding if a race is finished or not int raceState : "speed.exe", 0x5107A4; //Used for determining if player is in a chase or race int onChase : "speed.exe", 0x51D3D8; int onRace : "speed.exe", 0x5B3828; //Used for determining if player has exited shop or carlot/has started a nmg run int inShop : "speed.exe", 0x51C160, 0x118; //Used for Quick Race Mode stuff int raceStart : "speed.exe", 0x511EF0; int raceCP : "speed.exe", 0x51E000, 0x44; float completion : "speed.exe", 0x52FD98, 0x2F8, 0x50; } init { //Starting stopwatch from game detection point vars.Stopwatch = new Stopwatch(); vars.Stopwatch.Start(); //Original 1.2 speed.exe if (modules.First().ModuleMemorySize == 0x67F000) { version = "v1.2"; } //Original 1.3 speed.exe else if (modules.First().ModuleMemorySize == 0x680000) { version = "v1.3"; } //Cracked 1.3 speed.exe (RELOADED) else if (modules.First().ModuleMemorySize == 0x678E4E) { version = "v1.3"; } } startup { //Used for checking current split index and handling quick race mode resets vars.timerModel = new TimerModel { CurrentState = timer }; //Contains bool values for controlling quick race mode interval splits vars.percentages = new List<bool> { false, false, false, false, false }; //Contains last race for every boss in 15 -> 1 order, used for boss split option vars.lastBossRaces = new List<string>{ "15_1_1_circuit_reversed", "15_2_1_sprint_reverse", "14_2_2_r_sprint", "12_1_2_circuit", "12_1_2_r_circuit", "10_7_3_drag", "9_2_1_sprint", "8_7_5_drag", "7_2_3_p2p", "6_5_2_speedtraprace", "5_2_1_r_sprint", "4_5_1_r_speedtrap", "3_1_2_circuit", "2_2_1_sprint", "1_2_3_sprint" }; settings.Add("quickracemode", false, "Quick Race Mode"); settings.SetToolTip("quickracemode", "Handles starts, splits and resets for quick race (IL) conditions."); settings.Add("racecpsplit", false, "Race Checkpoint Splits", "quickracemode"); settings.SetToolTip("racecpsplit", "Split when you go through in race checkpoints."); settings.Add("raceintervalsplit", true, "Race Interval Splits", "quickracemode"); settings.SetToolTip("raceintervalsplit", "Split at every 20 percent interval of race completion."); settings.Add("12specific", true, "1.2 Specific Settings"); settings.Add("commonsettings", true, "Common Settings"); settings.Add("lapglitchsplit", true, "First Lap Glitches Split", "12specific"); settings.SetToolTip("lapglitchsplit", "Split when you start career after first lap glitches."); settings.Add("resumecareersplit", true, "Mid Run Lap Glitches Split", "12specific"); settings.SetToolTip("resumecareersplit", "Split when you resume career after doing lap glitches mid run."); settings.Add("introsplit", true, "Intro Split", "commonsettings"); settings.SetToolTip("introsplit", "Split after the partial race with the intro cutscene."); settings.Add("prologuesplit", true, "Prologue Split", "commonsettings"); settings.SetToolTip("prologuesplit", "Split after the last prologue race with Razor."); settings.Add("safehousesplit", true, "Safe House Split", "commonsettings"); settings.SetToolTip("safehousesplit", "Split when you enter safe house for the first time after buying your starter car."); settings.Add("shopsplit", true, "Shop Split", "commonsettings"); settings.SetToolTip("shopsplit", "Split when you exit a car lot or an upgrade shop."); settings.Add("racesplit", true, "Race Split", "commonsettings"); settings.SetToolTip("racesplit", "Split when you win a race."); settings.Add("camerasplit", true, "Camera Split", "commonsettings"); settings.SetToolTip("camerasplit", "Split when completing a Speedtrap Milestone in free roam."); settings.Add("bosssplit", false, "Boss Split", "commonsettings"); settings.SetToolTip("bosssplit", "Split when defeating a boss by winning the last boss race. Does nothing if Race Split setting is also activated."); settings.Add("markersplit", true, "Marker Split", "commonsettings"); settings.SetToolTip("markersplit", "Split on the first loading screen after choosing markers."); settings.Add("copchasesplit", true, "Police Chase Split", "commonsettings"); settings.SetToolTip("copchasesplit", "Split when you escape a police chase."); settings.Add("bustedsplit", false, "Busted Split", "commonsettings"); settings.SetToolTip("bustedsplit", "Split after getting busted."); settings.Add("gameoversplit", false, "Game Over Split", "commonsettings"); settings.SetToolTip("gameoversplit", "Split when the game over screen appears. Intended to be used for Career Bad Ending category."); settings.Add("bridgejumpsplit", true, "Bridge Jump Split", "commonsettings"); settings.SetToolTip("bridgejumpsplit", "Split when you trigger the bridge jump cutscene."); } update { //Checking for simrate after 10 secs of game being launched if (vars.Stopwatch.Elapsed.TotalSeconds >= 10.0 && current.frametime.ToString("0.00000000").Remove(0, 2) != "01666667") { vars.Stopwatch.Stop(); DialogResult res = MessageBox.Show("SimRate Detected", "Confirmation", MessageBoxButtons.OK, MessageBoxIcon.Information); } //Not allowing time controls if game version is not detected or simrate is detected if (version == "" || current.frametime.ToString("0.00000000").Remove(0, 2) != "01666667") { return false; } //Used for resetting time interval splits and for the timer itself while saving golds/pb if ((timer.CurrentPhase == TimerPhase.Ended || timer.CurrentPhase == TimerPhase.NotRunning) && settings["quickracemode"] && old.raceStart != current.raceStart && current.raceStart == 32767) { vars.percentages = new List<bool> { false, false, false, false, false }; vars.timerModel.Reset(); } } isLoading { //Every normal loading screen if (current.loadingScreen1 == 32767 || current.loadingScreen2 == 24 || current.loadingScreen2 == 0 || current.gamestateID == 16) { return true; } //Special loading screen being: entering the safe house for the first time and entering free roam for the first time //Still needs fixing timer being paused until player continues even though loading has been completed else if (current.gamestateID == 32) { //Exclude FMVs from being counted to loadless if (current.loadingScreen2 == 34) { return false; } else { return true; } //Loading screens for mid race restarts } else if (current.onRace == 257 && current.restartLoad) { return true; } else { return false; } } start { //Quick race menu start if (!settings["quickracemode"] && version == "v1.2" && ((current.selectedMenu == 3 && current.start == 60 && old.start != current.start) || (current.selectedMenu == 3 && old.selectedMenu != current.selectedMenu))) { return true; } //Direct career or challenge series start else if (!settings["quickracemode"] && (current.selectedMenu == 1 && old.inShop == 88 && current.inShop == 21) || (current.selectedMenu == 2 && current.loadingScreen2 == 24)) { return true; //Start on racestart at "go" for quick race mode } else if (settings["quickracemode"] && old.raceStart == 32767 && current.raceStart == 0 && current.onRace == 257) { return true; } else { return false; } } split { //Differentiating normal splits and quick race mode splits if (!settings["quickracemode"]) { //Split after first lap glitches if (version == "v1.2" && settings["lapglitchsplit"] && timer.CurrentSplitIndex == 0 && ((old.fmvName != current.fmvName && current.fmvName == "storyfmv_rac01") || (old.inShop == 88 && current.inShop == 84))) { return true; } //Split when resuming career else if (version == "v1.2" && timer.CurrentSplitIndex > 0 && old.selectedMenu != current.selectedMenu && current.selectedMenu == 1 && settings["resumecareersplit"]) { return true; } //Split before Ronnie prologue race else if (old.fmvName != current.fmvName && current.fmvName == "storyfmv_cro06" && settings["introsplit"]) { return true; } //Split after Razor prologue race else if (old.fmvName != current.fmvName && current.fmvName == "storyfmv_bus12" && settings["prologuesplit"]) { return true; } //Split after entering Safe House for the first time else if (old.fmvName != current.fmvName && current.fmvName == "storyfmv_saf25" && settings["safehousesplit"]) { return true; } //Split when exiting car lot or upgrade shop else if ((old.inShop == 111 || old.inShop == 72) && old.inShop != current.inShop && settings["shopsplit"]) { return true; } //Split after winning any race else if (current.raceState == 256 && old.raceState == 0 && current.onRace == 257 && settings["racesplit"]) { return true; } //Split after triggering a free roam camera else if (current.raceState == 256 && old.raceState == 0 && current.onRace != 257 && settings["camerasplit"]) { return true; } //Split after winning the last boss race else if (current.raceState == 256 && old.raceState == 0 && current.onRace == 257 && (vars.lastBossRaces.Contains(current.trackID) || vars.lastBossRaces.Contains(current.trackID.Substring(0, current.trackID.Length - 4))) && !settings["racesplit"] && settings["bosssplit"]) { return true; } //Split after choosing markers else if (!string.IsNullOrEmpty(old.fmvName) && !old.fmvName.Contains("blacklist_15") && old.fmvName.Contains("blacklist_") && old.fmvName != current.fmvName && settings["markersplit"]) { return true; } //Split after escaping Police Chases else if (old.onChase == 1 && current.onChase == 0 && current.onRace != 257 && (old.loadingScreen1 != 32767 && old.loadingScreen2 != 24 && old.loadingScreen2 != 0 && old.gamestateID != 16) && (current.trackID != "epic_pursuit" && current.trackID != "epic_pursuit.vlt") && settings["copchasesplit"]) { return true; } //Split after getting busted else if (current.onChase == 1 && current.loadingScreen1 == 32767 && old.loadingScreen1 != current.loadingScreen1 && settings["bustedsplit"]) { return true; } //Split when game over screen appears else if (current.gameover == 10 && old.gameover != current.gameover && current.inShop == 84 && settings["gameoversplit"]) { return true; } //Split when final bridge jump NIS plays else if (old.nisName != current.nisName && current.nisName == "EndingNis04" && settings["bridgejumpsplit"]) { return true; } else { return false; } } else if (settings["quickracemode"]) { //Split after each 20% interval in the race besides finish line/100% if (settings["raceintervalsplit"] && (int)current.completion >= 20 && (int)current.completion < 40 && !vars.percentages[0]) { vars.percentages[0] = true; return true; } else if (settings["raceintervalsplit"] && (int)current.completion >= 40 && (int)current.completion < 60 && !vars.percentages[1]) { vars.percentages[1] = true; return true; } else if (settings["raceintervalsplit"] && (int)current.completion >= 60 && (int)current.completion < 80 && !vars.percentages[2]) { vars.percentages[2] = true; return true; } else if (settings["raceintervalsplit"] && (int)current.completion >= 80 && (int)current.completion < 100 && !vars.percentages[3]) { vars.percentages[3] = true; return true; //Split after every new checkpoint in the race besides finish line } else if (settings["racecpsplit"] && current.raceCP != old.raceCP && !((int)current.completion >= 97 && current.raceCP == 0)) { return true; //Split after crossing finish line } else if ((int)current.completion >= 100 && current.onRace == 257 && !vars.percentages[4]) { vars.percentages[4] = true; return true; } else { return false; } } } reset { //Reset function is only used for quick race mode, handles resetting race interval splits if (settings["quickracemode"] && old.raceStart != current.raceStart && current.raceStart == 32767) { vars.percentages = new List<bool> { false, false, false, false, false }; return true; } else { return false; } } exit { timer.IsGameTimePaused = false; }