Forked from jbzdarkid/LiveSplit.TheTalosPrinciple.asl
Last active
September 18, 2016 16:24
-
-
Save YaLTeR/a9bc9616b33832cf2110421861e434f2 to your computer and use it in GitHub Desktop.
Autosplitter for The Talos Principle
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
state("Talos") {} | |
init { | |
var gameDir = Path.GetDirectoryName(modules.First().FileName); | |
var path = ""; | |
if (game.Is64Bit()) { | |
path = gameDir.TrimEnd("\\Bin\\x64".ToCharArray()) + "\\Log\\Talos.log"; | |
} else { | |
path = gameDir.TrimEnd("\\Bin".ToCharArray()) + "\\Log\\Talos.log"; | |
} | |
try { // Wipe the log file in case there's leftover messages from last time | |
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Write, FileShare.ReadWrite); | |
fs.SetLength(0); | |
fs.Close(); | |
} catch {} | |
vars.reader = new StreamReader(new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)); | |
} | |
startup { | |
vars.currentWorld = ""; | |
vars.gameStarting = false; | |
vars.introCutscene = false; | |
vars.lastLines = 0; | |
vars.isLoading = false; | |
vars.doubleSplit = false; | |
vars.totalLoads = TimeSpan.FromSeconds(0); | |
vars.adminEnding = false; | |
vars.counterA6 = 0; | |
vars.counterB4 = 0; | |
settings.Add("Split on return to Nexus", true); | |
settings.Add("Split on tetromino collection", true); | |
settings.Add("Split on star collection", false); | |
settings.Add("Split on item unlocks", true); | |
settings.Add("Split on tetromino world doors", false); | |
settings.Add("Split on tetromino star doors", false); | |
settings.Add("Split on tetromino tower doors", true); | |
settings.Add("Split on star collection in the Nexus", false); | |
settings.Add("(DLC) Split on return to Hub", true); | |
settings.Add("(DLC) Split on puzzle doors", false); | |
} | |
update { | |
vars.line = vars.reader.ReadLine(); | |
if (vars.line != null) { | |
vars.line = vars.line.Substring(16); // Removes the date and log level from the line | |
} else { | |
vars.line = ""; | |
} | |
// Intro cutscene (booting up sequence) is excluded from IGT | |
if (vars.introCutscene && vars.line.StartsWith("Player profile saved")) { | |
vars.totalLoads = timer.CurrentTime.RealTime; | |
vars.introCutscene = false; | |
} | |
System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(@"^Started simulation on '.*?' in ([\d\.]*) seconds"); | |
System.Text.RegularExpressions.Match match = regex.Match(vars.line); | |
// Not removing the initial load (A1) because the run hasn't started yet | |
if (match.Success && timer.CurrentTime.RealTime != TimeSpan.FromSeconds(0)) { | |
var load = TimeSpan.FromSeconds(Single.Parse(match.Groups[1].Value)); | |
vars.totalLoads += load; | |
} | |
} | |
start { | |
// Only start for A1, since restore backup / continue should mostly be on other worlds. | |
if (vars.line.StartsWith("Started simulation on 'Content/Talos/Levels/Cloud_1_01.wld'")) { | |
vars.gameStarting = true; | |
} | |
// Ditto for Gehenna with the intro world. | |
if (vars.line.StartsWith("Started simulation on 'Content/Talos/Levels/DLC_01_Intro.wld'")) { | |
vars.gameStarting = true; | |
} | |
if (vars.gameStarting && vars.line.Contains("sound channels reinitialized.")) { | |
vars.gameStarting = false; | |
vars.introCutscene = true; | |
return true; | |
} | |
} | |
reset { | |
if (vars.line == "Saving talos progress upon game stop.") { | |
vars.currentWorld = ""; | |
vars.gameStarting = false; | |
vars.introCutscene = false; | |
vars.lastLines = 0; | |
vars.isLoading = false; | |
vars.doubleSplit = false; | |
vars.totalLoads = TimeSpan.FromSeconds(0); | |
vars.adminEnding = false; | |
vars.counterA6 = 0; | |
vars.counterB4 = 0; | |
return true; | |
} | |
} | |
gameTime { | |
if (vars.introCutscene) { | |
return TimeSpan.FromSeconds(0); | |
} | |
return timer.CurrentTime.RealTime - vars.totalLoads; | |
} | |
split { | |
// Map changes | |
if (vars.line.StartsWith("Changing over to")) { | |
var mapName = vars.line.Substring(17); | |
// Ensure 'restart checkpoint' doesn't trigger map change | |
if (mapName != vars.currentWorld) { | |
vars.currentWorld = mapName; | |
if (mapName == "Content/Talos/Levels/Nexus.wld") { | |
return settings["Split on return to Nexus"]; | |
} | |
if (mapName == "Content/Talos/Levels/DLC_01_Hub.wld") { | |
return settings["(DLC) Split on return to Hub"]; | |
} | |
} | |
} | |
// Sigil and star collection | |
if (vars.line.StartsWith("Picked:")) { | |
if (vars.doubleSplit) { | |
return false; | |
} | |
vars.doubleSplit = true; | |
var what = vars.line.Substring(8, 3); | |
if (what.StartsWith("**")) { | |
if (settings["Split on star collection"]) { | |
return true; | |
} else { | |
if (vars.currentWorld == "Content/Talos/Levels/Nexus.wld") { | |
return settings["Split on star collection in the Nexus"]; | |
} | |
} | |
} else { | |
if (!settings["Split on tetromino collection"]) { | |
return false; | |
} | |
// NL2 - Deception | |
// NZ2 - Bichromatic Entaglement | |
// NL3 - A Door Too Far | |
if (what == "NL2" || what == "NZ2" || what == "NL3") { | |
return (++vars.counterA6 == 3); | |
} | |
// NL8 - Wrap Around the Corner | |
// NT4 - Redundant Power Supply | |
// NT3 - The Right Angle | |
// NL7 - A Box Up High | |
if (what == "NL8" || what == "NT4" || what == "NT3" || what == "NL7") { | |
return (++vars.counterB4 == 3); | |
} | |
return true; | |
} | |
} else { | |
vars.doubleSplit = false; // DLC Double-split prevention | |
} | |
// Arranger puzzles | |
if (vars.line.StartsWith("Puzzle \"") && vars.line.Contains("\" solved")) { | |
var puzzle = vars.line.Substring(8); | |
if (puzzle.StartsWith("Mechanic")) { | |
return settings["Split on item unlocks"]; | |
} | |
if (puzzle.StartsWith("Door")) { | |
return settings["Split on tetromino world doors"]; | |
} | |
if (puzzle.StartsWith("SecretDoor")) { | |
return settings["Split on tetromino star doors"]; | |
} | |
if (puzzle.StartsWith("Nexus")) { | |
return settings["Split on tetromino tower doors"]; | |
} | |
if (puzzle.StartsWith("DLC_01_Secret")) { | |
return settings["(DLC) Split on puzzle doors"]; | |
} | |
if (puzzle.StartsWith("DLC_01_Hub")) { | |
vars.adminEnding = true; // Admin puzzle door solved, so the Admin is saved. | |
return settings["(DLC) Split on puzzle doors"]; | |
} | |
} | |
if (vars.currentWorld == "Content/Talos/Levels/Islands_03.wld") { // Base game Messenger Ending | |
return vars.line.StartsWith("USER:"); // Line differs in languages. | |
} | |
if (vars.currentWorld == "Content/Talos/Levels/Nexus.wld") { // Base game Transcendence Ending | |
return (vars.line == "USER: /transcend"); | |
} | |
if (vars.currentWorld == "Content/Talos/Levels/Nexus.wld") { // Base game Eternalize Ending | |
return (vars.line == "USER: /eternalize"); | |
} | |
if (vars.currentWorld == "Content/Talos/Levels/DLC_01_Hub.wld") { // Any DLC ending | |
if (vars.line == "Save Talos Progress: entered terminal") { | |
vars.lastLines = 0; | |
} | |
if (vars.line.StartsWith("USER:")) { | |
vars.lastLines++; | |
if (vars.adminEnding) { // If admin is saved, it takes 5 lines to end the game | |
return (vars.lastLines == 5); | |
} else { // In all other endings, game ends on the 4th dialogue after entering the terminal | |
return (vars.lastLines == 4); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment