diff options
-rw-r--r-- | Taiji.asl | 122 |
1 files changed, 98 insertions, 24 deletions
diff --git a/Taiji.asl b/Taiji.asl index 080dbd9..dffc3c4 100644 --- a/Taiji.asl +++ b/Taiji.asl | |||
@@ -1,9 +1,11 @@ | |||
1 | state("Taiji") | 1 | // Autosplitter script for Taiji, by hatkirby. |
2 | { | 2 | // |
3 | // v9.10.2022, v9.12.2022.6 | 3 | // Requires v9.17.2022 or later. |
4 | int solveCount: "GameAssembly.dll", 0x0168ED88, 0x80, 0x100, 0xD94; | 4 | // |
5 | byte10 worldsCompleted: "GameAssembly.dll", 0x015C8010, 0x48, 0x40, 0x80, 0x290, 0xB8, 0x10, 0x20; | 5 | // Massive thanks to the game developer, mvandevander, for working with me to |
6 | } | 6 | // make this possible. |
7 | |||
8 | state("Taiji") {} | ||
7 | 9 | ||
8 | startup | 10 | startup |
9 | { | 11 | { |
@@ -13,34 +15,106 @@ startup | |||
13 | 15 | ||
14 | settings.Add("solveCount", true, "Split on solve count increasing"); | 16 | settings.Add("solveCount", true, "Split on solve count increasing"); |
15 | settings.Add("world", false, "Split on completing a world"); | 17 | settings.Add("world", false, "Split on completing a world"); |
18 | settings.Add("tutorial", false, "Split on Tutorial completion"); | ||
19 | settings.Add("black", true, "Split on Black ending"); | ||
20 | settings.Add("white", false, "Split on White ending"); | ||
16 | 21 | ||
17 | vars.log("Autosplitter loaded"); | 22 | vars.log("Autosplitter loaded"); |
18 | } | 23 | } |
19 | 24 | ||
20 | onStart | 25 | init |
26 | { | ||
27 | // magic byte array format: | ||
28 | // [0-7]: 7b 08 ec f9 87 1d b7 d6 (random bytes used for sigscanning) | ||
29 | // [8]: New file flag. Gets set to 1 when "start a new game" is selected. | ||
30 | // Gets reset to 0 when the pause menu is opened. | ||
31 | // [9-17]: A copy of the world completion flags. | ||
32 | // [18]: Solve count / 256. | ||
33 | // [19]: Solve count % 256. | ||
34 | // [20]: Tutorial completion flag. | ||
35 | // [21]: Black ending flag. Gets set to 1 when the square that starts the | ||
36 | // interactive ending is clicked. | ||
37 | // [22]: White ending flag. Gets set to 1 when the square that enables the | ||
38 | // prison is clicked. | ||
39 | // [23]: Loading flag. Set to 1 during loads, 0 otherwise. | ||
40 | IntPtr ptr = IntPtr.Zero; | ||
41 | foreach (var page in game.MemoryPages(true).Reverse()) { | ||
42 | var scanner = new SignatureScanner(game, page.BaseAddress, (int)page.RegionSize); | ||
43 | ptr = scanner.Scan(new SigScanTarget(0, "7b 08 ec f9 87 1d b7 d6")); | ||
44 | if (ptr != IntPtr.Zero) { | ||
45 | break; | ||
46 | } | ||
47 | } | ||
48 | if (ptr == IntPtr.Zero) { | ||
49 | throw new Exception("Could not find magic autosplitter array!"); | ||
50 | } | ||
51 | vars.newFileFlag = new MemoryWatcher<byte>(ptr + 8); | ||
52 | vars.worldCompletion = new List<MemoryWatcher<byte>>(); | ||
53 | for (int i = 0; i < 9; i++) { | ||
54 | vars.worldCompletion.Add(new MemoryWatcher<byte>(ptr + 9 + i)); | ||
55 | } | ||
56 | vars.solveCountHigh = new MemoryWatcher<byte>(ptr + 18); | ||
57 | vars.solveCountLow = new MemoryWatcher<byte>(ptr + 19); | ||
58 | vars.tutorialCompletion = new MemoryWatcher<byte>(ptr + 20); | ||
59 | vars.blackEnding = new MemoryWatcher<byte>(ptr + 21); | ||
60 | vars.whiteEnding = new MemoryWatcher<byte>(ptr + 22); | ||
61 | vars.loadingFlag = new MemoryWatcher<byte>(ptr + 23); | ||
62 | |||
63 | vars.log(String.Format("Magic autosplitter array: {0}", ptr.ToString("X"))); | ||
64 | } | ||
65 | |||
66 | update | ||
67 | { | ||
68 | vars.newFileFlag.Update(game); | ||
69 | vars.tutorialCompletion.Update(game); | ||
70 | vars.blackEnding.Update(game); | ||
71 | vars.whiteEnding.Update(game); | ||
72 | vars.loadingFlag.Update(game); | ||
73 | |||
74 | vars.solveCountHigh.Update(game); | ||
75 | vars.solveCountLow.Update(game); | ||
76 | current.solveCount = vars.solveCountHigh.Current * 256 + vars.solveCountLow.Current; | ||
77 | |||
78 | int curWorlds = 0; | ||
79 | for (int i = 0; i < 9; i++) { | ||
80 | vars.worldCompletion[i].Update(game); | ||
81 | if (vars.worldCompletion[i].Current == 1) { | ||
82 | curWorlds++; | ||
83 | } | ||
84 | } | ||
85 | current.numWorlds = curWorlds; | ||
86 | } | ||
87 | |||
88 | start | ||
21 | { | 89 | { |
22 | vars.maxSolve = 0; | 90 | return vars.newFileFlag.Old == 0 && vars.newFileFlag.Current == 1; |
23 | vars.numWorlds = 0; | ||
24 | } | 91 | } |
25 | 92 | ||
26 | split | 93 | split |
27 | { | 94 | { |
28 | if (settings["solveCount"] && current.solveCount > vars.maxSolve) { | 95 | if (settings["solveCount"] && current.solveCount > old.solveCount) { |
29 | vars.log(String.Format("Solve count increased from {0} to {1}", vars.maxSolve, current.solveCount)); | 96 | vars.log(String.Format("Solve count increased from {0} to {1}", old.solveCount, current.solveCount)); |
30 | vars.maxSolve = current.solveCount; | ||
31 | return true; | 97 | return true; |
32 | } | 98 | } |
33 | if (settings["world"]) { | 99 | if (settings["world"] && current.numWorlds > old.numWorlds) { |
34 | int curWorlds = 0; | 100 | vars.log(String.Format("World count increased from {0} to {1}", old.numWorlds, current.numWorlds)); |
35 | foreach (byte b in current.worldsCompleted) { | 101 | return true; |
36 | if (b == 1) { | 102 | } |
37 | curWorlds += 1; | 103 | if (settings["tutorial"] && vars.tutorialCompletion.Old == 0 && vars.tutorialCompletion.Current == 1) { |
38 | } | 104 | vars.log("Split on tutorial completion"); |
39 | } | 105 | return true; |
40 | if (curWorlds > vars.numWorlds) { | ||
41 | vars.log(String.Format("World count increased from {0} to {1}", vars.numWorlds, curWorlds)); | ||
42 | vars.numWorlds = curWorlds; | ||
43 | return true; | ||
44 | } | ||
45 | } | 106 | } |
107 | if (settings["black"] && vars.blackEnding.Old == 0 && vars.blackEnding.Current == 1) { | ||
108 | vars.log("Split on Black ending"); | ||
109 | return true; | ||
110 | } | ||
111 | if (settings["white"] && vars.whiteEnding.Old == 0 && vars.whiteEnding.Current == 1) { | ||
112 | vars.log("Split on White ending"); | ||
113 | return true; | ||
114 | } | ||
115 | } | ||
116 | |||
117 | isLoading | ||
118 | { | ||
119 | return vars.loadingFlag.Current == 1; | ||
46 | } | 120 | } |