state("Among Ashes", "v1.0.1h / v1.0.2") { bool gameStarted : "GameAssembly.dll", 0x24DA208, 0xB8, 0x0, 0x54; int currentMainStoryEvent : "GameAssembly.dll", 0x24C7858, 0xB8, 0x0, 0x28; bool RealWorldInCutscene : "GameAssembly.dll", 0x24E4870, 0xB8, 0x0, 0x42; bool NightCallInCutscene : "GameAssembly.dll", 0x24E47F8, 0xB8, 0x0, 0x42; int MainMenuState : "GameAssembly.dll", 0x24DA208, 0xB8, 0x0, 0xE8; int TLGameState : "GameAssembly.dll", 0x24A6470, 0xB8, 0x0, 0x20; int FinalBossWeakspots : "GameAssembly.dll", 0x24C4E28, 0xB8, 0x0, 0x38; } state("Among Ashes", "v1.0.2b") { bool gameStarted : "GameAssembly.dll", 0x24DA218, 0xB8, 0x0, 0x54; int currentMainStoryEvent : "GameAssembly.dll", 0x24C7868, 0xB8, 0x0, 0x28; bool RealWorldInCutscene : "GameAssembly.dll", 0x24E4880, 0xB8, 0x0, 0x42; bool NightCallInCutscene : "GameAssembly.dll", 0x24E4808, 0xB8, 0x0, 0x42; int MainMenuState : "GameAssembly.dll", 0x24DA218, 0xB8, 0x0, 0xE8; int TLGameState : "GameAssembly.dll", 0x24A6480, 0xB8, 0x0, 0x20; int FinalBossWeakspots : "GameAssembly.dll", 0x24C4E38, 0xB8, 0x0, 0x40; bool invokedEnd : "GameAssembly.dll", 0x24C4E38, 0xB8, 0x0, 0xD8; } state("Among Ashes", "v1.0.2c") { bool gameStarted : "GameAssembly.dll", 0x24DA218, 0xB8, 0x0, 0x54; int currentMainStoryEvent : "GameAssembly.dll", 0x24C7868, 0xB8, 0x0, 0x28; bool RealWorldInCutscene : "GameAssembly.dll", 0x24E4880, 0xB8, 0x0, 0x42; bool NightCallInCutscene : "GameAssembly.dll", 0x24E4808, 0xB8, 0x0, 0x42; int MainMenuState : "GameAssembly.dll", 0x24DA218, 0xB8, 0x0, 0xE8; int TLGameState : "GameAssembly.dll", 0x24A6480, 0xB8, 0x0, 0x20; int FinalBossWeakspots : "GameAssembly.dll", 0x24C4E38, 0xB8, 0x0, 0x40; bool invokedEnd : "GameAssembly.dll", 0x24C4E38, 0xB8, 0x0, 0xD8; } state("Among Ashes", "v1.0.2d") { bool gameStarted : "GameAssembly.dll", 0x24DB218, 0xB8, 0x0, 0x54; int currentMainStoryEvent : "GameAssembly.dll", 0x24C8868, 0xB8, 0x0, 0x28; bool RealWorldInCutscene : "GameAssembly.dll", 0x24E5880, 0xB8, 0x0, 0x42; bool NightCallInCutscene : "GameAssembly.dll", 0x24E5808, 0xB8, 0x0, 0x42; int MainMenuState : "GameAssembly.dll", 0x24DB218, 0xB8, 0x0, 0xE8; int TLGameState : "GameAssembly.dll", 0x24A7480, 0xB8, 0x0, 0x20; byte FinalBossWeakspots : "GameAssembly.dll", 0x24C5E38, 0xB8, 0x0, 0x40; bool invokedEnd : "GameAssembly.dll", 0x24C5E38, 0xB8, 0x0, 0xD8; } state("Among Ashes", "v1.0.3c") { bool gameStarted : "GameAssembly.dll", 0x24DC268, 0xB8, 0x0, 0x54; int currentMainStoryEvent : "GameAssembly.dll", 0x24C9898, 0xB8, 0x0, 0x28; bool RealWorldInCutscene : "GameAssembly.dll", 0x24E68B0, 0xB8, 0x0, 0x42; bool NightCallInCutscene : "GameAssembly.dll", 0x24E6840, 0xB8, 0x0, 0x42; int MainMenuState : "GameAssembly.dll", 0x24DC268, 0xB8, 0x0, 0xE8; int TLGameState : "GameAssembly.dll", 0x24A84B0, 0xB8, 0x0, 0x20; byte FinalBossWeakspots : "GameAssembly.dll", 0x24C6E68, 0xB8, 0x0, 0x40; bool invokedEnd : "GameAssembly.dll", 0x24C6E68, 0xB8, 0x0, 0xD8; } startup { Assembly.Load(File.ReadAllBytes("Components/asl-help")).CreateInstance("Unity"); vars.Helper.GameName = "Among Ashes"; vars.Helper.LoadSceneManager = true; dynamic[,] _settings = { { "Splits", true, "Splits", null }, { "MSE_3", true, "Reach Demon Blood Boss", "Splits" }, { "MSE_10", true, "Night Call Downloaded", "Splits" }, { "Item_Key_Katherine_0", true, "Picked up Katherine's Room Key", "Splits" }, { "Item_Key_WWF2_0", true, "Pick Up West Wing Key", "Splits" }, { "MSE_11", true, "3 - Baton the dead lady", "Splits" }, { "Item_Key_Kitchen_0", true, "Office Lock Puzzle Complete & Kitchen Key Get", "Splits" }, { "Item_Bloodstained_Book_0", true, "Pick Up Bloodstained Book", "Splits" }, { "Item_MorgueKey_Bigfoot_0", true, "Opened Lab & Pick Up Morgue Key", "Splits" }, { "Item_MorgueKey_Fairy_0", false, "Pick Up Fairy Key", "Splits" }, { "Item_MorgueKey_Vampire_0", false, "Pick Up Vampire Key", "Splits" }, { "Item_MorgueKey_Mummy_0", false, "Pick Up Mummy Key", "Splits" }, { "Item_MorgueKey_Ghost_0", false, "Pick Up Ghost Key", "Splits" }, { "Item_Key_Gardens_0", true, "Lab Box Puzzle Complete & Garden Key Pick Up", "Splits" }, { "Item_Key_Servants_0", true, "Pick Up Servants Key", "Splits" }, { "Item_Key_Greenhouse_0", true, "Pick Up Greenhouse Key", "Splits" }, { "Enemy_FRANCIS_BOSS", true, "Killed Dr. Stoker in Greenhouse", "Splits" }, { "TLGameDone", true, "Tree of Life Game Done", "Splits" }, { "Item_Lighter_0", true, "Picked up Lighter from Music Box & Get In-Game", "Splits"}, { "Item_Key_Ankh_0", true, "Picked up Anhk key", "Splits" }, { "Item_LockerKey_Red_0", true, "Pick Up Underground Locker Key Red", "Splits" }, { "Item_LockerKey_Green_0", true, "Pick Up Underground Locker Key Green", "Splits" }, { "Item_Key_Amalia_0", true, "Pick up Amalia's Key", "Splits" }, { "LookingAtFingermanFNC", true, "Fake Night Call Ended & Looking at Finger Man", "Splits" }, { "Item_LockerKey_Blue_0", true, "Pick up Locker Key Blue", "Splits" }, { "Item_Key_Black_0", true, "Pick up Black Key", "Splits" }, { "FinalBossDead", true, "Final Boss Dead", "Splits" }, { "MSE_61", true, "End Credits", "Splits" }, }; vars.Helper.Settings.Create(_settings); vars.Helper.AlertLoadless(); vars.CompletedSplits = new List<string>(); } init { string gameVersion = vars.Helper.ReadString(32, ReadStringType.UTF8, "UnityPlayer.dll", 0x1CA4940, 0x3D0); vars.Log(gameVersion); switch (gameVersion) { case "v1.0.1h": version = "v1.0.1h / v1.0.2"; break; case "v1.0.2": version = "v1.0.1h / v1.0.2"; break; case "v1.0.2b": version = "v1.0.2b"; break; case "v1.0.2c": version = "v1.0.2c"; break; case "v1.0.2d": version = "v1.0.2d"; break; case "v1.0.3c": version = "v1.0.3c"; break; } vars.NoInCutsene = false; current.activeScene = ""; vars.BossFightActive = false; vars.AfterFinalBossCutsceneFix = false; } onStart { vars.CompletedSplits.Clear(); vars.BossFightActive = false; vars.NoInCutsene = false; vars.AfterFinalBossCutsceneFix = false; timer.IsGameTimePaused = true; } start { return current.gameStarted == true && current.MainMenuState == 7 && old.RealWorldInCutscene == false && current.RealWorldInCutscene == true; } update { switch(version) { case "v1.0.1h / v1.0.2": current.Items = vars.Helper.ReadList<IntPtr>("GameAssembly.dll", 0x24E0788, 0xB8, 0x0, 0x68); current.Enemies = vars.Helper.ReadList<IntPtr>("GameAssembly.dll", 0x24E0788, 0xB8, 0x0, 0x38); break; case "v1.0.2b": current.Items = vars.Helper.ReadList<IntPtr>("GameAssembly.dll", 0x24E0798, 0xB8, 0x0, 0x68); current.Enemies = vars.Helper.ReadList<IntPtr>("GameAssembly.dll", 0x24E0798, 0xB8, 0x0, 0x38); break; case "v1.0.2c": current.Items = vars.Helper.ReadList<IntPtr>("GameAssembly.dll", 0x24E0798, 0xB8, 0x0, 0x68); current.Enemies = vars.Helper.ReadList<IntPtr>("GameAssembly.dll", 0x24E0798, 0xB8, 0x0, 0x38); break; case "v1.0.2d": current.Items = vars.Helper.ReadList<IntPtr>("GameAssembly.dll", 0x24E1798, 0xB8, 0x0, 0x68); current.Enemies = vars.Helper.ReadList<IntPtr>("GameAssembly.dll", 0x24E1798, 0xB8, 0x0, 0x38); break; case "v1.0.3c": current.Items = vars.Helper.ReadList<IntPtr>("GameAssembly.dll", 0x24E27E8, 0xB8, 0x0, 0x68); current.Enemies = vars.Helper.ReadList<IntPtr>("GameAssembly.dll", 0x24E27E8, 0xB8, 0x0, 0x38); break; default: break; } if(!String.IsNullOrWhiteSpace(vars.Helper.Scenes.Active.Name)) current.activeScene = vars.Helper.Scenes.Active.Name; if(current.activeScene != old.activeScene) vars.Log("active: Old: \"" + old.activeScene + "\", Current: \"" + current.activeScene + "\""); if (vars.NoInCutsene == false && current.currentMainStoryEvent == 17) { if (current.RealWorldInCutscene == true) vars.NoInCutsene = true; } if (vars.NoInCutsene == true && current.currentMainStoryEvent == 19 && old.RealWorldInCutscene == true && current.RealWorldInCutscene == false) vars.NoInCutsene = false; if (vars.NoInCutsene == false && current.currentMainStoryEvent == 30) { if (current.RealWorldInCutscene == true) vars.NoInCutsene = true; } if (vars.NoInCutsene == true && old.RealWorldInCutscene == true && current.RealWorldInCutscene == false) vars.NoInCutsene = false; if (old.FinalBossWeakspots == 0 && current.FinalBossWeakspots == 8) vars.BossFightActive = true; if (vars.CompletedSplits.Contains("FinalBossDead") && current.NightCallInCutscene == true && old.RealWorldInCutscene == true && current.RealWorldInCutscene == false) { vars.AfterFinalBossCutsceneFix = true; vars.Log("End Cutscene Fix is active"); } } split { // Main Splits if (current.currentMainStoryEvent == 3 || current.currentMainStoryEvent == 10 || current.currentMainStoryEvent == 43 || current.currentMainStoryEvent == 61) { if (settings["MSE_" + current.currentMainStoryEvent.ToString()] && old.currentMainStoryEvent != current.currentMainStoryEvent && !vars.CompletedSplits.Contains("MSE_" + current.currentMainStoryEvent.ToString())) { vars.CompletedSplits.Add("MSE_" + current.currentMainStoryEvent.ToString()); vars.Log("---SPLIT 1"); return true; } } // Items Splits if (old.Items.Count < current.Items.Count) { var len = vars.Helper.Read<int>(current.Items[current.Items.Count - 1] + 0x10); var name = vars.Helper.ReadString(len * 2, ReadStringType.UTF16, current.Items[current.Items.Count - 1] + 0x14); vars.Log(name); if (!vars.CompletedSplits.Contains("Item_" + name)) { vars.CompletedSplits.Add("Item_" + name); vars.Log("---SPLIT 2"); return settings["Item_" + name]; } } // Enemies Splits (Dr. Stoker Only) if (old.Enemies.Count < current.Enemies.Count) { var len = vars.Helper.Read<int>(current.Enemies[current.Enemies.Count - 1] + 0x10); var name = vars.Helper.ReadString(len * 2, ReadStringType.UTF16, current.Enemies[current.Enemies.Count - 1] + 0x14); vars.Log(name); if (!vars.CompletedSplits.Contains("Enemy_" + name) && name == "FRANCIS_BOSS") { vars.CompletedSplits.Add("Enemy_" + name); vars.Log("---SPLIT 3"); return settings["Enemy_" + name]; } } // Tree of Life Game Done Split if (settings["TLGameDone"] && old.TLGameState != 4 && current.TLGameState == 4 && !vars.CompletedSplits.Contains("TLGameDone")) { vars.CompletedSplits.Add("TLGameDone"); vars.Log("---SPLIT 4"); return true; } // Fake Night Call & Looking At Fingerman Split if (settings["LookingAtFingermanFNC"] && (current.currentMainStoryEvent == 51 || current.currentMainStoryEvent == 52) && old.RealWorldInCutscene == false && current.RealWorldInCutscene == true && !vars.CompletedSplits.Contains("LookingAtFingermanFNC")) { vars.CompletedSplits.Add("LookingAtFingermanFNC"); vars.Log("---SPLIT 5"); return true; } // Final Boss Split switch(version) { case "v1.0.1h / v1.0.2": if (settings["FinalBossDead"] && vars.AfterFinalBossCutsceneFix == true && vars.BossFightActive == true && old.FinalBossWeakspots <= 2 && current.FinalBossWeakspots <= 1 && old.NightCallInCutscene == false && current.NightCallInCutscene == true && !vars.CompletedSplits.Contains("FinalBossDead")) { vars.CompletedSplits.Add("FinalBossDead"); vars.Log("---SPLIT 6"); return true; } break; case "v1.0.2b": if (settings["FinalBossDead"] && vars.AfterFinalBossCutsceneFix == true && current.invokedEnd == true && old.NightCallInCutscene == false && current.NightCallInCutscene == true && !vars.CompletedSplits.Contains("FinalBossDead")) { vars.CompletedSplits.Add("FinalBossDead"); vars.Log("---SPLIT 6"); return true; } break; case "v1.0.2c": if (settings["FinalBossDead"] && vars.AfterFinalBossCutsceneFix == true && current.invokedEnd == true && old.NightCallInCutscene == false && current.NightCallInCutscene == true && !vars.CompletedSplits.Contains("FinalBossDead")) { vars.CompletedSplits.Add("FinalBossDead"); vars.Log("---SPLIT 6"); return true; } break; case "v1.0.2d": if (settings["FinalBossDead"] && vars.AfterFinalBossCutsceneFix == true && current.invokedEnd == true && old.NightCallInCutscene == false && current.NightCallInCutscene == true && !vars.CompletedSplits.Contains("FinalBossDead")) { vars.CompletedSplits.Add("FinalBossDead"); vars.Log("---SPLIT 6"); return true; } break; case "v1.0.3c": if (settings["FinalBossDead"] && vars.AfterFinalBossCutsceneFix == true && current.invokedEnd == true && old.NightCallInCutscene == false && current.NightCallInCutscene == true && !vars.CompletedSplits.Contains("FinalBossDead")) { vars.CompletedSplits.Add("FinalBossDead"); vars.Log("---SPLIT 6"); return true; } break; default: break; } } isLoading { if (vars.NoInCutsene == true) return false; else if (vars.AfterFinalBossCutsceneFix == true) return current.RealWorldInCutscene; else return current.activeScene == "LoadingScreen" || current.RealWorldInCutscene || current.NightCallInCutscene; }