From 4029f94aff24205cd82a7158f64069426b205941 Mon Sep 17 00:00:00 2001 From: Christopher Torres Date: Fri, 27 Apr 2018 15:15:52 -0400 Subject: [PATCH] Update SonicGenerations.asl Cleaned up the code a little. Changed the condition in the split function to better match the conditions of hitting the goal. --- SonicGenerations.asl | 216 +++++++++++++++++++++++-------------------- 1 file changed, 114 insertions(+), 102 deletions(-) diff --git a/SonicGenerations.asl b/SonicGenerations.asl index 231e606..459235a 100644 --- a/SonicGenerations.asl +++ b/SonicGenerations.asl @@ -1,16 +1,30 @@ -state("SonicGenerations", "v2") +state("SonicGenerations", "latest") { - float StageTime : 0x01A0BE5C, 0x08, 0x184; - float TotalStageTime : 0x01A0BE5C, 0x08, 0x188; - bool stageLoading : 0x01A0BE5C, 0x08, 0x1a8; + // This only ticks if you have control of Sonic. + float stage_time : 0x01A0BE5C, 0x08, 0x184; - // This address (hitGoal) does the job most of the time (if you die it messes this address up). - ulong hitGoal : 0x01A0BE5C, 0x08, 0xa0; - - byte paused : 0x01A0BE5C, 0x08,0xD0; - string6 stageName : 0x01A0BE5C, 0x08, 0x88, 0x00; - byte stageType : 0x01A0BE5C, 0x08, 0x88, 0x07; - byte inComboSeq : 0x01A0BE5C, 0x08, 0x19c; + // This ticks from the start of the stage all the way to after the goal is hit + float total_stage_time : 0x01A0BE5C, 0x08, 0x188; + + // When a loading screen is up, this will be true + bool stage_loading : 0x01A0BE5C, 0x08, 0x1a8; + + // When you touch the goal, this section of 8 bytes are modified. + // We however can not use this reliabily as it is changed when you die, or talk to some NPCs. + // I believe this has to do with either GUIs appering on the screen or your animation state. + ulong goal_hit : 0x01A0BE5C, 0x08, 0xa0; + + // If the game is paused, this is true + byte is_paused : 0x01A0BE5C, 0x08,0xD0; + + // Name of the stage we are currently on + string6 stage_name : 0x01A0BE5C, 0x08, 0x88, 0x00; + + // This is not zero when in a cutscene (Needs more testing). + byte stage_state : 0x01A0BE5C, 0x08, 0x88, 0x07; + + // When you hit a combo bumper or ring, this becomes true. (Just here because it may be useful later) + bool in_combo_seq : 0x01A0BE5C, 0x08, 0x19c; } startup @@ -19,13 +33,13 @@ startup settings.Add("Real_time", true, "Track Real Time"); settings.Add("Game_time", false, "Use Game time"); settings.Add("loading_time", true, "Include loading time in runtime"); - + settings.Add("catagory", true, "Run Catagory"); settings.CurrentDefaultParent = "catagory"; settings.Add("any_percent", true); settings.Add("act1_only", false); settings.Add("act2_only", false); - + settings.CurrentDefaultParent = null; } @@ -33,53 +47,38 @@ init { // We are connected to the process now if (modules.First().ModuleMemorySize == 0x1CAB000) - version = "v2"; + version = "latest"; - //StageID - // pam = Overworld - // ghz = Green Hill - // cpz = Chemical Plant - // ssz = Sky Sanctuary - // sph = Speed Highway - // cte = City Escape - // ssh = Seaside Hill - // csc = Crisis City - // euc = Rooftop Run - // pla = Planet Wisp - - //Bosses - // bde = DeathEgg Robot - // bpc = Perfect Chaos - // bne = Egg Dragoon - // blb = Time Eater - vars.stageDict = new Dictionary(); - vars.stageDict.Add("pam", 1); - vars.stageDict.Add("ghz", 2); - vars.stageDict.Add("cpz", 3); - vars.stageDict.Add("ssz", 4); - vars.stageDict.Add("sph", 5); - vars.stageDict.Add("cte", 6); - vars.stageDict.Add("ssh", 7); - vars.stageDict.Add("csc", 8); - vars.stageDict.Add("euc", 9); - vars.stageDict.Add("pla", 10); - - vars.stageDict.Add("bde", 11); - vars.stageDict.Add("bpc", 12); - vars.stageDict.Add("bne", 13); - vars.stageDict.Add("blb", 14); + // stage_id + vars.stage_table = new Dictionary(); + vars.stage_table.Add("pam", 01); // pam = Overworld + vars.stage_table.Add("ghz", 02); // ghz = Green Hill + vars.stage_table.Add("cpz", 03); // cpz = Chemical Plant + vars.stage_table.Add("ssz", 04); // ssz = Sky Sanctuary + vars.stage_table.Add("sph", 05); // sph = Speed Highway + vars.stage_table.Add("cte", 06); // cte = City Escape + vars.stage_table.Add("ssh", 07); // ssh = Seaside Hill + vars.stage_table.Add("csc", 08); // csc = Crisis City + vars.stage_table.Add("euc", 09); // euc = Rooftop Run + vars.stage_table.Add("pla", 10); // pla = Planet Wisp + + // Bosses + vars.stage_table.Add("bde", 11); // bde = DeathEgg Robot + vars.stage_table.Add("bpc", 12); // bpc = Perfect Chaos + vars.stage_table.Add("bne", 13); // bne = Egg Dragoon + vars.stage_table.Add("blb", 14); // blb = Time Eater vars.act = 0; - vars.stageID = 0; - vars.stageCode = ""; - vars.inBoss = false; - vars.finalBoss = false; - vars.prevStageEnd = false; - vars.currentStageEnd = false; - + vars.stage_id = 0; + vars.stage_code = ""; + vars.in_boss = false; + vars.in_final_boss = false; + vars.prev_stage_state = false; + vars.current_stage_state = false; + Action DebugOutput = (text) => { - print("[SonicGenerations Autosplitter] "+text); - }; + print("[SonicGenerations Autosplitter] "+text); + }; vars.DebugOutput = DebugOutput; vars.DebugOutput("test"); } @@ -88,65 +87,67 @@ exit { // Connected game closed. Do stuff if needed here vars.act = 0; - vars.stageID = 0; - vars.stageCode = ""; - vars.inBoss = false; - vars.finalBoss = false; - vars.prevStageEnd = false; - vars.currentStageEnd = false; + vars.stage_id = 0; + vars.stage_code = ""; + vars.in_boss = false; + vars.in_final_boss = false; + vars.prev_stage_state = false; + vars.current_stage_state = false; } start { - if(current.stageName != null && current.stageName.Length > 3) + if(current.stage_name != null && current.stage_name.Length > 3) { - vars.act = Convert.ToByte(current.stageName[3].ToString()); + vars.act = Convert.ToByte(current.stage_name[3].ToString()); } - if (settings["any_percent"] == true && current.stageLoading == true && vars.stageID == 1) { - vars.DebugOutput("Any percent timer started"); - return true; - } - else if (settings["act1_only"] == true && vars.act == 1 && current.stageLoading == true) { + if (settings["any_percent"] == true && current.stage_loading == true && vars.stage_id == 1) { + vars.DebugOutput("Any percent timer started"); + return true; + } + else if (settings["act1_only"] == true && vars.act == 1 && current.stage_loading == true) { vars.DebugOutput("Act1 Timer started"); - return true; - } - else if (settings["act2_only"] == true && vars.act == 2 && current.stageLoading == true) { + return true; + } + else if (settings["act2_only"] == true && vars.act == 2 && current.stage_loading == true) { vars.DebugOutput("Act2 Timer started"); - return true; - } + return true; + } return false; } update { // Reset some of the varibles that we are about to set - vars.inBoss = false; - vars.finalBoss = false; - - if(current.stageName != old.stageName) + vars.in_boss = false; + vars.in_final_boss = false; + + // if the new if statement in the split function works, we won't need this here + if(current.stage_name != old.stage_name) { - vars.prevStageEnd = vars.currentStageEnd = false; + vars.prev_stage_state = vars.current_stage_state = false; } - - if(current.stageType == 0x00 && current.stageName != null) // This is always 0 unless a cutscene is running - { - if(current.stageName.Length > 3) + + if( current.stage_state == 0x00 && + current.stage_name != null) // This is always 0 unless a cutscene is running + { + if(current.stage_name.Length > 3) { - vars.act = Convert.ToByte(current.stageName[3].ToString()); - vars.stageCode = "" + current.stageName[0] + current.stageName[1] + current.stageName[2]; + vars.act = Convert.ToByte(current.stage_name[3].ToString()); + vars.stage_code = "" + current.stage_name[0] + current.stage_name[1] + current.stage_name[2]; byte tempId = 0; - if(vars.stageDict.TryGetValue(vars.stageCode.ToString(), out tempId)) + if(vars.stage_table.TryGetValue(vars.stage_code.ToString(), out tempId)) { - vars.stageID = tempId; + vars.stage_id = tempId; } } - else if (current.stageName.Length == 3) + else if (current.stage_name.Length == 3) { - vars.inBoss = true; - if(current.stageName == "blb") + vars.in_boss = true; + if(current.stage_name == "blb") { - vars.finalBoss = true; + vars.in_final_boss = true; vars.DebugOutput("In final boss"); } @@ -156,22 +157,27 @@ update { vars.DebugOutput("In cutscene"); } - - //vars.DebugOutput("name: "+current.stageName.ToString()+" id:"+vars.stageID.ToString()+" act:"+vars.act.ToString()+" isloading:"+current.stageLoading.ToString()); - - if(current.hitGoal != old.hitGoal) + + // if the new if statement in the split function works, we won't need this here + if(current.goal_hit != old.goal_hit) { - vars.currentStageEnd = true; + vars.current_stage_state = true; } + + //vars.DebugOutput("name: "+current.stage_name.ToString()+" id:"+vars.stage_id.ToString()+" act:"+vars.act.ToString()+" isloading:"+current.stage_loading.ToString()); } split { - //TODO See if I can update different segments - //TODO Need to find out how to tell if the stage ended - if(vars.stageID > 1 && vars.currentStageEnd != vars.prevStageEnd) + //TODO See if I can update different splits here? +// if(vars.stage_id > 1 && vars.current_stage_state != vars.prev_stage_state) + if( (vars.stage_id > 1) && + (current.is_paused == false) && + (current.stage_time - old.stage_time < 0.5f) && + (current.total_stage_time != old.total_stage_time) && + (current.stage_name == old.stage_name) ) { - vars.prevStageEnd = vars.currentStageEnd; + vars.prev_stage_state = vars.current_stage_state; if(settings["any_percent"] == true) { return true; @@ -196,5 +202,11 @@ isLoading return true; // Only count loading if we set it up like that - return (!settings["loading_time"] && ((vars.stageID == 1) ||current.stageLoading)); -} \ No newline at end of file + return (!settings["loading_time"] && ((vars.stage_id == 1) || current.stage_loading)); +} + +gameTime +{ + //TODO create a buffer for the time here as the total_stage_time resets when changing stages + return TimeSpan.FromSeconds( Convert.ToDouble(current.total_stage_time) ); +}