//Pragmata Demo Autosplitter V1.0.0 (4 April 2026) //Supports IGT and Game Splits for the demo //Script & Pointers by TheDementedSalad //Cutscene/Event pointers by Rumii state("PRAGMATA_SKETCHBOOK"){} startup { Assembly.Load(File.ReadAllBytes("Components/asl-help")).CreateInstance("Basic"); vars.Helper.Settings.CreateFromXml("Components/PragDemo.Settings.xml"); // Asks user to change to game time if LiveSplit is currently set to Real Time. if (timer.CurrentTimingMethod == TimingMethod.RealTime) { var timingMessage = MessageBox.Show ( "This game uses In Game Time as the main timing method.\n"+ "LiveSplit is currently set to show Real Time (RTA).\n"+ "Would you like to set the timing method to Game Time?", "LiveSplit | Resident Evil 4 (2023)", MessageBoxButtons.YesNo,MessageBoxIcon.Question ); if (timingMessage == DialogResult.Yes) { timer.CurrentTimingMethod = TimingMethod.GameTime; } } } init { switch (modules.First().ModuleMemorySize) { } IntPtr GameClock = vars.Helper.ScanRel(3, "4c 8b 05 ?? ?? ?? ?? 48 89 7c 24 ?? 49 8b c8"); IntPtr ObjectiveManager = vars.Helper.ScanRel(3, "4c 8b 15 ?? ?? ?? ?? 0f b7 57"); IntPtr DemoMediator = vars.Helper.ScanRel(3, "48 8b 15 ?? ?? ?? ?? 45 8b e0 48 8b fa"); IntPtr AppEventManager = vars.Helper.ScanRel(3, "48 8B 15 ?? ?? ?? ?? 48 8B F1 48 39 58 18 48 0F 45 D3 74"); vars.Helper["GameElapsedTime"] = vars.Helper.Make(GameClock, 0x18); vars.Helper["DemoSpendingTime"] = vars.Helper.Make(GameClock, 0x20); vars.Helper["PauseSpendingTime"] = vars.Helper.Make(GameClock, 0x28); vars.Helper["ObjectiveSize"] = vars.Helper.Make(ObjectiveManager, 0x30, 0x18); vars.Helper["MovieID"] = vars.Helper.MakeString(AppEventManager, 0x30, 0x20, 0x10, 0x20, 0x20, 0x38, 0x10, 0x28, 0x14); vars.Helper["MovieID"].FailAction = MemoryWatcher.ReadFailAction.SetZeroOrNull; vars.Helper["MovieStatus"] = vars.Helper.Make(AppEventManager, 0x30, 0x20, 0x10, 0x20, 0x83); vars.Helper["MovieStatus"].FailAction = MemoryWatcher.ReadFailAction.SetZeroOrNull; vars.Helper["CutsceneID"] = vars.Helper.MakeString(AppEventManager, 0x30, 0x28, 0x10, 0x20, 0x20, 0x38, 0x10, 0x28, 0x14); vars.Helper["CutsceneID"].FailAction = MemoryWatcher.ReadFailAction.SetZeroOrNull; vars.Helper["CutsceneStatus"] = vars.Helper.Make(AppEventManager, 0x30, 0x28, 0x10, 0x20, 0x28, 0xA4); vars.Helper["CutsceneStatus"].FailAction = MemoryWatcher.ReadFailAction.SetZeroOrNull; vars.Quests = new List(); vars.completedSplits = new HashSet(); vars.Objective = new Dictionary(); vars.ObjectiveManager = ObjectiveManager; vars.PendingSplits = 0; } onStart { vars.Quests.Clear(); vars.completedSplits.Clear(); vars.Objective.Clear(); vars.PendingSplits = 0; } start { return current.CutsceneID == "cs6010" && string.IsNullOrEmpty(old.CutsceneID); } update { //print(modules.First().ModuleMemorySize.ToString()); vars.Helper.Update(); vars.Helper.MapPointers(); current.Quests = new uint[current.ObjectiveSize]; for (int i = 0; i < current.ObjectiveSize; i++) current.Quests[i] = vars.Helper.Read(vars.ObjectiveManager, 0x30, 0x10, 0x20 + (i * 0x8), 0x10); if(!string.IsNullOrEmpty(current.CutsceneID)){ current.Cutscene = current.CutsceneID.Substring(2,4); } if(!string.IsNullOrEmpty(current.MovieID)){ current.Movie = current.MovieID.Substring(2,4); } } gameTime { return TimeSpan.FromSeconds((current.GameElapsedTime - current.DemoSpendingTime - current.PauseSpendingTime) / 1000000.0); } split { string MStartSetting = ""; string MCompSetting = ""; string CutsceneSetting = ""; string MovieSetting = ""; for (int i = 0; i < current.ObjectiveSize; i++){ uint mission = vars.Helper.Read(vars.ObjectiveManager, 0x30, 0x10, 0x20 + (i * 0x8), 0x10); byte chapter = vars.Helper.Read(vars.ObjectiveManager, 0x30, 0x10, 0x20 + (i * 0x8), 0x20); byte complete = vars.Helper.Read(vars.ObjectiveManager, 0x30, 0x10, 0x20 + (i * 0x8), 0x24); byte oldComplete; if (vars.Objective.TryGetValue(mission, out oldComplete)) { if (complete == 2 && oldComplete != 2){ MCompSetting = mission + "_" + chapter + "_" + complete; } if(!vars.completedSplits.Contains(MCompSetting)){ if (settings.ContainsKey(MCompSetting) && settings[MCompSetting]){ vars.PendingSplits++; } } if (!string.IsNullOrEmpty(MCompSetting)) vars.Log(MCompSetting); } vars.Objective[mission] = complete; } if(current.ObjectiveSize != old.ObjectiveSize){ for (int i = 0; i < current.ObjectiveSize; i++) { var missions = current.Quests[i]; if(missions != 0){ MStartSetting = missions + "_New"; } if(!vars.completedSplits.Contains(MStartSetting)){ if (settings.ContainsKey(MStartSetting) && settings[MStartSetting]){ vars.PendingSplits++; } } if (!string.IsNullOrEmpty(MStartSetting)) vars.Log(MStartSetting); } } if(!string.IsNullOrEmpty(current.CutsceneID) && current.CutsceneStatus && !old.CutsceneStatus){ CutsceneSetting = "cs_" + current.Cutscene; if (!string.IsNullOrEmpty(CutsceneSetting)) vars.Log(CutsceneSetting); if(!vars.completedSplits.Contains(CutsceneSetting)){ if (settings.ContainsKey(CutsceneSetting) && settings[CutsceneSetting]){ vars.PendingSplits++; } } } if(!string.IsNullOrEmpty(current.MovieID) && current.MovieStatus && !old.MovieStatus){ MovieSetting = "ev_" + current.Movie; if (!string.IsNullOrEmpty(MovieSetting)) vars.Log(MovieSetting); if(!vars.completedSplits.Contains(MovieSetting)){ if (settings.ContainsKey(MovieSetting) && settings[MovieSetting]){ vars.PendingSplits++; } } } if (vars.PendingSplits > 0) { vars.PendingSplits--; vars.completedSplits.Add(MStartSetting); vars.completedSplits.Add(MCompSetting); vars.completedSplits.Add(CutsceneSetting); vars.completedSplits.Add(MovieSetting); return true; } } isLoading { return true; } reset { return current.CutsceneID == "cs6010" && string.IsNullOrEmpty(old.CutsceneID); } exit { //pauses timer if the game crashes timer.IsGameTimePaused = true; vars.Helper.Texts.RemoveAll(); }