summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--App/App.vcxproj3
-rw-r--r--App/Main.cpp63
-rw-r--r--App/Version.h4
-rw-r--r--GithubPackage/WitnessRandomizer.exebin0 -> 379392 bytes
-rw-r--r--GithubPackage/WitnessRandomizerInstaller.msibin0 -> 389632 bytes
-rw-r--r--GithubPackage/setup.exebin0 -> 791040 bytes
-rw-r--r--Installer/Installer.vdproj12
-rw-r--r--Source/ChallengeRandomizer.cpp218
-rw-r--r--Source/ChallengeRandomizer.h5
-rw-r--r--Source/Memory.h4
-rw-r--r--Source/Randomizer.cpp29
-rw-r--r--Source/Randomizer.h3
12 files changed, 195 insertions, 146 deletions
diff --git a/App/App.vcxproj b/App/App.vcxproj index 2597b8d..9b10e92 100644 --- a/App/App.vcxproj +++ b/App/App.vcxproj
@@ -85,6 +85,7 @@
85 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> 85 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
86 <LinkIncremental>false</LinkIncremental> 86 <LinkIncremental>false</LinkIncremental>
87 <TargetName>WitnessRandomizer</TargetName> 87 <TargetName>WitnessRandomizer</TargetName>
88 <OutDir>..\GithubPackage\</OutDir>
88 </PropertyGroup> 89 </PropertyGroup>
89 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> 90 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
90 <ClCompile> 91 <ClCompile>
@@ -140,6 +141,7 @@
140 <EnableCOMDATFolding>true</EnableCOMDATFolding> 141 <EnableCOMDATFolding>true</EnableCOMDATFolding>
141 <OptimizeReferences>true</OptimizeReferences> 142 <OptimizeReferences>true</OptimizeReferences>
142 <GenerateDebugInformation>true</GenerateDebugInformation> 143 <GenerateDebugInformation>true</GenerateDebugInformation>
144 <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
143 </Link> 145 </Link>
144 </ItemDefinitionGroup> 146 </ItemDefinitionGroup>
145 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> 147 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -162,6 +164,7 @@
162 <EnableCOMDATFolding>true</EnableCOMDATFolding> 164 <EnableCOMDATFolding>true</EnableCOMDATFolding>
163 <OptimizeReferences>true</OptimizeReferences> 165 <OptimizeReferences>true</OptimizeReferences>
164 <GenerateDebugInformation>true</GenerateDebugInformation> 166 <GenerateDebugInformation>true</GenerateDebugInformation>
167 <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
165 </Link> 168 </Link>
166 </ItemDefinitionGroup> 169 </ItemDefinitionGroup>
167 <ItemGroup> 170 <ItemGroup>
diff --git a/App/Main.cpp b/App/Main.cpp index 7e802e9..82600bf 100644 --- a/App/Main.cpp +++ b/App/Main.cpp
@@ -18,8 +18,10 @@
18#define IDC_WRITE 0x407 18#define IDC_WRITE 0x407
19#define IDC_DUMP 0x408 19#define IDC_DUMP 0x408
20#define IDT_RANDOMIZED 0x409 20#define IDT_RANDOMIZED 0x409
21#define IDC_TOGGLELASERS 0x410
22#define IDC_TOGGLESNIPES 0x411
21 23
22HWND hwndSeed, hwndRandomize, hwndDebug; 24HWND hwndSeed, hwndRandomize;
23// int panel = 0x18AF; 25// int panel = 0x18AF;
24int panel = 0x33D4; 26int panel = 0x33D4;
25std::shared_ptr<Panel> _panel; 27std::shared_ptr<Panel> _panel;
@@ -38,13 +40,15 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
38 seedIsRNG = false; 40 seedIsRNG = false;
39 } 41 }
40 switch (LOWORD(wParam)) { 42 switch (LOWORD(wParam)) {
41 // Speed checkbox 43 // Checkboxes
42 case IDC_TOGGLESPEED: 44 case IDC_TOGGLESPEED:
43 if (IsDlgButtonChecked(hwnd, IDC_TOGGLESPEED)) { 45 CheckDlgButton(hwnd, IDC_TOGGLESPEED, !IsDlgButtonChecked(hwnd, IDC_TOGGLESPEED));
44 CheckDlgButton(hwnd, IDC_TOGGLESPEED, BST_UNCHECKED); 46 break;
45 } else { 47 case IDC_TOGGLELASERS:
46 CheckDlgButton(hwnd, IDC_TOGGLESPEED, BST_CHECKED); 48 CheckDlgButton(hwnd, IDC_TOGGLELASERS, !IsDlgButtonChecked(hwnd, IDC_TOGGLELASERS));
47 } 49 break;
50 case IDC_TOGGLESNIPES:
51 CheckDlgButton(hwnd, IDC_TOGGLESNIPES, !IsDlgButtonChecked(hwnd, IDC_TOGGLESNIPES));
48 break; 52 break;
49 53
50 // Randomize button 54 // Randomize button
@@ -70,30 +74,27 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
70 if (randomizer->GameIsRandomized()) break; 74 if (randomizer->GameIsRandomized()) break;
71 Random::SetSeed(seed); 75 Random::SetSeed(seed);
72 76
73 77 // Show seed and force redraw
74 std::wstringstream debug;
75
76 std::wstring seedString = std::to_wstring(seed); 78 std::wstring seedString = std::to_wstring(seed);
77 SetWindowText(hwndRandomize, L"Randomizing..."); 79 SetWindowText(hwndRandomize, L"Randomizing...");
78 SetWindowText(hwndSeed, seedString.c_str()); 80 SetWindowText(hwndSeed, seedString.c_str());
79 RedrawWindow(hwnd, NULL, NULL, RDW_UPDATENOW); 81 RedrawWindow(hwnd, NULL, NULL, RDW_UPDATENOW);
80 82
83 // Randomize, then apply settings
81 randomizer->Randomize(); 84 randomizer->Randomize();
82 debug << Random::RandInt(0, 1000) << " "; 85 if (IsDlgButtonChecked(hwnd, IDC_TOGGLESPEED)) randomizer->AdjustSpeed();
83 debug << Random::RandInt(0, 1000) << "\n"; 86 if (IsDlgButtonChecked(hwnd, IDC_TOGGLELASERS)) randomizer->RandomizeLasers();
84 debug << Random::RandInt(0, 1000) << " "; 87 if (IsDlgButtonChecked(hwnd, IDC_TOGGLESNIPES)) randomizer->PreventSnipes();
85 debug << Random::RandInt(0, 1000); 88
86 SetWindowText(hwndDebug, debug.str().c_str()); 89 // Cleanup, and set timer for "randomization done"
87 if (IsDlgButtonChecked(hwnd, IDC_TOGGLESPEED)) { 90 SetWindowText(hwndRandomize, L"Randomized!");
88 randomizer->AdjustSpeed();
89 }
90 SetWindowText(hwndRandomize, L"Randomized!");
91 SetTimer(hwnd, IDT_RANDOMIZED, 10000, NULL); 91 SetTimer(hwnd, IDT_RANDOMIZED, 10000, NULL);
92 break; 92 break;
93 } 93 }
94 94
95 case IDT_RANDOMIZED: 95 case IDT_RANDOMIZED:
96 SetWindowText(hwndRandomize, L"Randomize"); 96 SetWindowText(hwndRandomize, L"Randomize");
97 randomizer->GameIsRandomized(); // "Check" if the game is randomized to update the last known safe frame.
97 break; 98 break;
98 case IDC_READ: 99 case IDC_READ:
99 _panel = std::make_shared<Panel>(panel); 100 _panel = std::make_shared<Panel>(panel);
@@ -171,11 +172,22 @@ int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmd
171 10, 52, 12, 12, hwnd, (HMENU)IDC_TOGGLESPEED, hInstance, NULL); 172 10, 52, 12, 12, hwnd, (HMENU)IDC_TOGGLESPEED, hInstance, NULL);
172 CreateWindow(L"STATIC", L"Speed up various autoscrollers", 173 CreateWindow(L"STATIC", L"Speed up various autoscrollers",
173 WS_TABSTOP | WS_VISIBLE | WS_CHILD | SS_LEFT, 174 WS_TABSTOP | WS_VISIBLE | WS_CHILD | SS_LEFT,
174 27, 50, 205, 16, hwnd, NULL, hInstance, NULL); 175 27, 50, 210, 16, hwnd, NULL, hInstance, NULL);
176
177 CreateWindow(L"BUTTON", L"",
178 WS_VISIBLE | WS_CHILD | BS_CHECKBOX,
179 10, 72, 12, 12, hwnd, (HMENU)IDC_TOGGLELASERS, hInstance, NULL);
180 CreateWindow(L"STATIC", L"Randomize laser activations",
181 WS_TABSTOP | WS_VISIBLE | WS_CHILD | SS_LEFT,
182 27, 70, 210, 16, hwnd, NULL, hInstance, NULL);
175 183
176 hwndDebug = CreateWindow(L"STATIC", L"", 184 CreateWindow(L"BUTTON", L"",
185 WS_VISIBLE | WS_CHILD | BS_CHECKBOX,
186 10, 92, 12, 12, hwnd, (HMENU)IDC_TOGGLESNIPES, hInstance, NULL);
187 CheckDlgButton(hwnd, IDC_TOGGLESNIPES, TRUE);
188 CreateWindow(L"STATIC", L"Prevent sniping certain puzzles",
177 WS_TABSTOP | WS_VISIBLE | WS_CHILD | SS_LEFT, 189 WS_TABSTOP | WS_VISIBLE | WS_CHILD | SS_LEFT,
178 200, 200, 100, 100, hwnd, NULL, hInstance, NULL); 190 27, 90, 210, 16, hwnd, NULL, hInstance, NULL);
179 191
180 /* 192 /*
181 CreateWindow(L"BUTTON", L"", 193 CreateWindow(L"BUTTON", L"",
@@ -206,13 +218,6 @@ int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmd
206 WS_TABSTOP | WS_VISIBLE | WS_CHILD | SS_LEFT, 218 WS_TABSTOP | WS_VISIBLE | WS_CHILD | SS_LEFT,
207 27, 50, 205, 16, hwnd, NULL, hInstance, NULL); 219 27, 50, 205, 16, hwnd, NULL, hInstance, NULL);
208 220
209 CreateWindow(L"BUTTON", L"",
210 WS_VISIBLE | WS_CHILD | BS_CHECKBOX,
211 10, 52, 12, 12, hwnd, (HMENU)IDC_BANSNIPES, hInstance, NULL);
212 CreateWindow(L"STATIC", L"Prevent sniping certain puzzles",
213 WS_TABSTOP | WS_VISIBLE | WS_CHILD | SS_LEFT,
214 27, 50, 205, 16, hwnd, NULL, hInstance, NULL);
215
216*/ 221*/
217 222
218 ShowWindow(hwnd, nCmdShow); 223 ShowWindow(hwnd, nCmdShow);
diff --git a/App/Version.h b/App/Version.h index 61473e6..1167925 100644 --- a/App/Version.h +++ b/App/Version.h
@@ -3,9 +3,9 @@
3#define TO_STRING2(s) L#s 3#define TO_STRING2(s) L#s
4#define TO_STRING(s) TO_STRING2(s) 4#define TO_STRING(s) TO_STRING2(s)
5 5
6#define MAJOR 4 6#define MAJOR 5
7#define MINOR 0 7#define MINOR 0
8#define PATCH 6 8#define PATCH 0
9 9
10#define VERSION_STR TO_STRING(MAJOR) L"." TO_STRING(MINOR) L"." TO_STRING(PATCH) 10#define VERSION_STR TO_STRING(MAJOR) L"." TO_STRING(MINOR) L"." TO_STRING(PATCH)
11#define VERSION MAJOR, MINOR, PATCH 11#define VERSION MAJOR, MINOR, PATCH
diff --git a/GithubPackage/WitnessRandomizer.exe b/GithubPackage/WitnessRandomizer.exe new file mode 100644 index 0000000..11a154e --- /dev/null +++ b/GithubPackage/WitnessRandomizer.exe
Binary files differ
diff --git a/GithubPackage/WitnessRandomizerInstaller.msi b/GithubPackage/WitnessRandomizerInstaller.msi new file mode 100644 index 0000000..b2afff9 --- /dev/null +++ b/GithubPackage/WitnessRandomizerInstaller.msi
Binary files differ
diff --git a/GithubPackage/setup.exe b/GithubPackage/setup.exe new file mode 100644 index 0000000..223753d --- /dev/null +++ b/GithubPackage/setup.exe
Binary files differ
diff --git a/Installer/Installer.vdproj b/Installer/Installer.vdproj index cd1c976..4677dbb 100644 --- a/Installer/Installer.vdproj +++ b/Installer/Installer.vdproj
@@ -27,7 +27,7 @@
27 "DisplayName" = "8:Debug" 27 "DisplayName" = "8:Debug"
28 "IsDebugOnly" = "11:TRUE" 28 "IsDebugOnly" = "11:TRUE"
29 "IsReleaseOnly" = "11:FALSE" 29 "IsReleaseOnly" = "11:FALSE"
30 "OutputFilename" = "8:WitnessRandomizerInstaller.msi" 30 "OutputFilename" = "8:..\\GithubPackage\\WitnessRandomizerInstaller.msi"
31 "PackageFilesAs" = "3:2" 31 "PackageFilesAs" = "3:2"
32 "PackageFileSize" = "3:-2147483648" 32 "PackageFileSize" = "3:-2147483648"
33 "CabType" = "3:1" 33 "CabType" = "3:1"
@@ -59,7 +59,7 @@
59 "DisplayName" = "8:Release" 59 "DisplayName" = "8:Release"
60 "IsDebugOnly" = "11:FALSE" 60 "IsDebugOnly" = "11:FALSE"
61 "IsReleaseOnly" = "11:TRUE" 61 "IsReleaseOnly" = "11:TRUE"
62 "OutputFilename" = "8:WitnessRandomizerInstaller.msi" 62 "OutputFilename" = "8:..\\GithubPackage\\WitnessRandomizerInstaller.msi"
63 "PackageFilesAs" = "3:2" 63 "PackageFilesAs" = "3:2"
64 "PackageFileSize" = "3:-2147483648" 64 "PackageFileSize" = "3:-2147483648"
65 "CabType" = "3:1" 65 "CabType" = "3:1"
@@ -162,15 +162,15 @@
162 { 162 {
163 "Name" = "8:Microsoft Visual Studio" 163 "Name" = "8:Microsoft Visual Studio"
164 "ProductName" = "8:Witness Randomizer" 164 "ProductName" = "8:Witness Randomizer"
165 "ProductCode" = "8:{ED6B3515-B039-4560-B97F-A61695CCDE5F}" 165 "ProductCode" = "8:{2AC8C329-8190-4A51-9861-5C922763C6F3}"
166 "PackageCode" = "8:{4C062EDD-4A06-4DC6-9C37-82A2BD37A0B5}" 166 "PackageCode" = "8:{05B49C89-4B7E-4E42-B061-3BAB51527E54}"
167 "UpgradeCode" = "8:{4CB5496B-A47E-41D3-B4A7-677E29AB7513}" 167 "UpgradeCode" = "8:{4CB5496B-A47E-41D3-B4A7-677E29AB7513}"
168 "AspNetVersion" = "8:2.0.50727.0" 168 "AspNetVersion" = "8:2.0.50727.0"
169 "RestartWWWService" = "11:FALSE" 169 "RestartWWWService" = "11:FALSE"
170 "RemovePreviousVersions" = "11:FALSE" 170 "RemovePreviousVersions" = "11:FALSE"
171 "DetectNewerInstalledVersion" = "11:TRUE" 171 "DetectNewerInstalledVersion" = "11:TRUE"
172 "InstallAllUsers" = "11:FALSE" 172 "InstallAllUsers" = "11:FALSE"
173 "ProductVersion" = "8:4.0.8" 173 "ProductVersion" = "8:5.0.0"
174 "Manufacturer" = "8:jbzdarkid" 174 "Manufacturer" = "8:jbzdarkid"
175 "ARPHELPTELEPHONE" = "8:" 175 "ARPHELPTELEPHONE" = "8:"
176 "ARPHELPLINK" = "8:https://www.github.com/jbzdarkid/witness-randomizer/issues" 176 "ARPHELPLINK" = "8:https://www.github.com/jbzdarkid/witness-randomizer/issues"
@@ -698,7 +698,7 @@
698 { 698 {
699 "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_F4835D5BBF3E437390127C4C49888F07" 699 "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_F4835D5BBF3E437390127C4C49888F07"
700 { 700 {
701 "SourcePath" = "8:..\\x64\\Release\\WitnessRandomizer.exe" 701 "SourcePath" = "8:..\\x64\\Debug\\WitnessRandomizer.exe"
702 "TargetName" = "8:" 702 "TargetName" = "8:"
703 "Tag" = "8:" 703 "Tag" = "8:"
704 "Folder" = "8:_8E9D847124D34D9D9008762077D816DE" 704 "Folder" = "8:_8E9D847124D34D9D9008762077D816DE"
diff --git a/Source/ChallengeRandomizer.cpp b/Source/ChallengeRandomizer.cpp index 0bc51f6..401771e 100644 --- a/Source/ChallengeRandomizer.cpp +++ b/Source/ChallengeRandomizer.cpp
@@ -16,116 +16,33 @@ int find(const std::vector<byte> &data, const std::vector<byte>& search, size_t
16 return -1; 16 return -1;
17} 17}
18 18
19// Reads the (relative!) address of the RNG, then shifts it to point at RNG2
19void ChallengeRandomizer::AdjustRng(int offset) { 20void ChallengeRandomizer::AdjustRng(int offset) {
20 int currentRng = _memory->ReadData<int>({offset}, 0x1)[0]; 21 int currentRng = _memory->ReadData<int>({offset}, 0x1)[0];
21 _memory->WriteData<int>({offset}, {currentRng + 0x20}); 22 _memory->WriteData<int>({offset}, {currentRng + 0x20});
22} 23}
23 24
25// Overwrite the pointer for the lightmap_generator (which is unused, afaict) to point to a secondary RNG.
26// Then, adjust all the RNG functions in challenge/doors to use this RNG.
24ChallengeRandomizer::ChallengeRandomizer(const std::shared_ptr<Memory>& memory, int seed) : _memory(memory) 27ChallengeRandomizer::ChallengeRandomizer(const std::shared_ptr<Memory>& memory, int seed) : _memory(memory)
25{ 28{
26 int RNG_ADDR = _memory->ReadData<int>({GLOBALS + 0x10}, 1)[0]; 29 RNG_ADDR = _memory->ReadData<int>({GLOBALS + 0x10}, 1)[0];
27 int RNG2_ADDR = _memory->ReadData<int>({GLOBALS + 0x30}, 1)[0]; 30 RNG2_ADDR = _memory->ReadData<int>({GLOBALS + 0x30}, 1)[0];
28 _memory->WriteData<int>({GLOBALS + 0x30}, {RNG_ADDR + 4}); 31 bool alreadyInjected = (RNG2_ADDR == RNG_ADDR + 4);
29 if (RNG2_ADDR == RNG_ADDR + 4) return; // Already applied hack 32
33 if (!alreadyInjected) _memory->WriteData<int>({GLOBALS + 0x30}, {RNG_ADDR + 4});
34 _memory->WriteData<int>({GLOBALS + 0x30, 0}, {seed});
30 35
31 int shuffle_integers = -1;
32 int cut_random_edges = -1;
33 int get_empty_decoration_slot = -1;
34 int get_empty_dot_spot = -1;
35 int add_exactly_this_many_bisection_dots = -1;
36 int make_a_shaper = -1;
37 int init_pattern_data_lotus = -1;
38 int reroll_lotus_eater_stuff = -1;
39 int do_lotus_minutes = -1;
40 int do_lotus_eighths = -1;
41 int do_success_side_effects = -1; 36 int do_success_side_effects = -1;
42 37
43 for (int i=0; i<0x200000; i+=0x1000) { 38 for (int i=0; i<0x200000; i+=0x1000) {
44 std::vector<byte> data = _memory->ReadData<byte>({i}, 0x1100); 39 std::vector<byte> data = _memory->ReadData<byte>({i}, 0x1100);
45 std::cout << data.size() << std::endl; 40 std::cout << data.size() << std::endl;
46 41
47 if (shuffle_integers == -1) { 42 if (!alreadyInjected) HandleSigScans(i, data);
48 int index = find(data, {0x48, 0x89, 0x5C, 0x24, 0x10, 0x56, 0x48, 0x83, 0xEC, 0x20, 0x48, 0x63, 0xDA, 0x48, 0x8B, 0xF1, 0x83, 0xFB, 0x01}); 43
49 if (index != -1) {
50 shuffle_integers = i + index;
51 AdjustRng(shuffle_integers + 0x23);
52 }
53 }
54 if (cut_random_edges == -1) {
55 int index = find(data, {0x89, 0x44, 0x24, 0x3C, 0x33, 0xC0, 0x85, 0xC0, 0x75, 0xFA});
56 if (index != -1) {
57 cut_random_edges = i + index - 0x22;
58 AdjustRng(cut_random_edges + 0x5D);
59 }
60 }
61 if (get_empty_decoration_slot == -1) {
62 int index = find(data, {0x57, 0x48, 0x83, 0xEC, 0x20, 0x8B, 0xB9, 0x38, 0x04}); // TODO: Sync versions
63 if (index != -1) {
64 get_empty_decoration_slot = i + index - 0x5;
65 AdjustRng(get_empty_decoration_slot + 0x16);
66 }
67 }
68 if (get_empty_dot_spot == -1) {
69 int index = find(data, {0xF7, 0xF3, 0x85, 0xD2, 0x74, 0xEC}); // TODO: Sync versions
70 if (index != -1) {
71 get_empty_dot_spot = i + index - 0x2E;
72 AdjustRng(get_empty_dot_spot + 0x23);
73 }
74 }
75 if (add_exactly_this_many_bisection_dots == -1) {
76 int index = find(data, {0x48, 0x8B, 0xB4, 0x24, 0xB8, 0x00, 0x00, 0x00, 0x48, 0x8B, 0xBC, 0x24, 0xB0, 0x00, 0x00, 0x00}); // TODO: Sync versions
77 if (index != -1) {
78 add_exactly_this_many_bisection_dots = i + index - 0x20;
79 AdjustRng(add_exactly_this_many_bisection_dots + 0x1C);
80 }
81 }
82 if (make_a_shaper == -1) {
83 int index = find(data, {0xF7, 0xE3, 0xD1, 0xEA, 0x8D, 0x0C, 0x52}); // TODO: Sync versions
84 if (index != -1) {
85 make_a_shaper = i + index - 0x19;
86 AdjustRng(make_a_shaper + 0x9);
87 AdjustRng(make_a_shaper + 0x35);
88 AdjustRng(make_a_shaper + 0x62);
89 }
90 }
91 if (/*Entity_Machine_Panel::*/init_pattern_data_lotus == -1) {
92 int index = find(data, {0x40, 0x55, 0x56, 0x48, 0x8D, 0x6C, 0x24, 0xB1}); // TODO: Sync versions
93 if (index != -1) {
94 init_pattern_data_lotus = i + index;
95 AdjustRng(init_pattern_data_lotus + 0x433);
96 AdjustRng(init_pattern_data_lotus + 0x45B);
97 AdjustRng(init_pattern_data_lotus + 0x5A7);
98 AdjustRng(init_pattern_data_lotus + 0x5D6);
99 AdjustRng(init_pattern_data_lotus + 0x6F6);
100 AdjustRng(init_pattern_data_lotus + 0xD17);
101 AdjustRng(init_pattern_data_lotus + 0xFDA);
102 }
103 }
104 if (/*Entity_Record_Player::*/reroll_lotus_eater_stuff == -1) {
105 int index = find(data, {0xB8, 0xAB, 0xAA, 0xAA, 0xAA, 0x41, 0xC1, 0xE8}); // TODO: Sync versions
106 if (index != -1) {
107 reroll_lotus_eater_stuff = i + index - 0x37;
108 AdjustRng(reroll_lotus_eater_stuff + 0x24);
109 AdjustRng(reroll_lotus_eater_stuff + 0x6B);
110 }
111 }
112 // These disable the random locations on timer panels, which would otherwise increment the RNG.
113 if (do_lotus_minutes == -1) {
114 int index = find(data, {0x0F, 0xBE, 0x6C, 0x08, 0xFF, 0x45}); // TODO: Sync versions
115 if (index != -1) {
116 do_lotus_minutes = i + index - 0x2B;
117 _memory->WriteData<byte>({do_lotus_minutes + 0x43B}, {0x31, 0xC0, 0x90, 0x90, 0x90}); // xor eax, eax ;RNG returns 0
118 _memory->WriteData<byte>({do_lotus_minutes + 0x5B3}, {0x31, 0xC0, 0x90, 0x90, 0x90}); // xor eax, eax ;RNG returns 0
119 }
120 }
121 if (do_lotus_eighths == -1) {
122 int index = find(data, {0x75, 0xF5, 0x0F, 0xBE, 0x44, 0x08, 0xFF}); // TODO: Sync versions
123 if (index != -1) {
124 do_lotus_eighths = i + index - 0x39;
125 _memory->WriteData<byte>({do_lotus_eighths + 0x1E7}, {0x31, 0xC0, 0x90, 0x90, 0x90}); // xor eax, eax ;RNG returns 0
126 }
127 }
128 // This injection ensures that the seed is set every time the challenge is started. 44 // This injection ensures that the seed is set every time the challenge is started.
45 // We always do this sigscan since it affects the seed.
129 if (do_success_side_effects == -1) { 46 if (do_success_side_effects == -1) {
130 int index = find(data, {0xFF, 0xC8, 0x99, 0x2B, 0xC2, 0xD1, 0xF8, 0x8B, 0xD0}); 47 int index = find(data, {0xFF, 0xC8, 0x99, 0x2B, 0xC2, 0xD1, 0xF8, 0x8B, 0xD0});
131 if (index != -1) { 48 if (index != -1) {
@@ -144,3 +61,114 @@ ChallengeRandomizer::ChallengeRandomizer(const std::shared_ptr<Memory>& memory,
144 } 61 }
145 } 62 }
146} 63}
64
65void ChallengeRandomizer::HandleSigScans(int i, const std::vector<byte>& data) {
66 static int shuffle_integers = -1;
67 static int shuffle_int = -1;
68 static int cut_random_edges = -1;
69 static int get_empty_decoration_slot = -1;
70 static int get_empty_dot_spot = -1;
71 static int add_exactly_this_many_bisection_dots = -1;
72 static int make_a_shaper = -1;
73 static int init_pattern_data_lotus = -1;
74 static int reroll_lotus_eater_stuff = -1;
75 static int do_lotus_minutes = -1;
76 static int do_lotus_tenths = -1;
77 static int do_lotus_eighths = -1;
78
79 if (shuffle_integers == -1) {
80 int index = find(data, {0x48, 0x89, 0x5C, 0x24, 0x10, 0x56, 0x48, 0x83, 0xEC, 0x20, 0x48, 0x63, 0xDA, 0x48, 0x8B, 0xF1, 0x83, 0xFB, 0x01});
81 if (index != -1) {
82 shuffle_integers = i + index;
83 AdjustRng(shuffle_integers + 0x23);
84 }
85 }
86 // shuffle<int>
87 if (shuffle_int == -1) {
88 int index = find(data, {0x33, 0xF6, 0x48, 0x8B, 0xD9, 0x39, 0x31, 0x7E, 0x51});
89 if (index != -1) {
90 shuffle_int = i + index - 0x16;
91 AdjustRng(shuffle_int + 0x12);
92 }
93 }
94 if (cut_random_edges == -1) {
95 int index = find(data, {0x89, 0x44, 0x24, 0x3C, 0x33, 0xC0, 0x85, 0xC0, 0x75, 0xFA});
96 if (index != -1) {
97 cut_random_edges = i + index - 0x22;
98 AdjustRng(cut_random_edges + 0x5D);
99 }
100 }
101 if (get_empty_decoration_slot == -1) {
102 int index = find(data, {0x42, 0x83, 0x3C, 0x80, 0x00, 0x75, 0xDF});
103 if (index != -1) {
104 get_empty_decoration_slot = i + index - 0x2D;
105 AdjustRng(get_empty_decoration_slot + 0x16);
106 }
107 }
108 if (get_empty_dot_spot == -1) {
109 int index = find(data, {0xF7, 0xF3, 0x85, 0xD2, 0x74, 0xEC});
110 if (index != -1) {
111 get_empty_dot_spot = i + index - 0x2E;
112 AdjustRng(get_empty_dot_spot + 0x23);
113 }
114 }
115 if (add_exactly_this_many_bisection_dots == -1) {
116 int index = find(data, {0x48, 0x8B, 0xB4, 0x24, 0xB8, 0x00, 0x00, 0x00, 0x48, 0x8B, 0xBC, 0x24, 0xB0, 0x00, 0x00, 0x00});
117 if (index != -1) {
118 add_exactly_this_many_bisection_dots = i + index - 0x20;
119 AdjustRng(add_exactly_this_many_bisection_dots + 0x1C);
120 }
121 }
122 if (make_a_shaper == -1) {
123 int index = find(data, {0xF7, 0xE3, 0xD1, 0xEA, 0x8D, 0x0C, 0x52});
124 if (index != -1) {
125 make_a_shaper = i + index - 0x19;
126 AdjustRng(make_a_shaper + 0x9);
127 AdjustRng(make_a_shaper + 0x35);
128 AdjustRng(make_a_shaper + 0x62);
129 }
130 }
131 if (/*Entity_Machine_Panel::*/init_pattern_data_lotus == -1) {
132 int index = find(data, {0x40, 0x55, 0x56, 0x48, 0x8D, 0x6C, 0x24, 0xB1});
133 if (index != -1) {
134 init_pattern_data_lotus = i + index;
135 AdjustRng(init_pattern_data_lotus + 0x433);
136 AdjustRng(init_pattern_data_lotus + 0x45B);
137 AdjustRng(init_pattern_data_lotus + 0x5A7);
138 AdjustRng(init_pattern_data_lotus + 0x5D6);
139 AdjustRng(init_pattern_data_lotus + 0x6F6);
140 AdjustRng(init_pattern_data_lotus + 0xD17);
141 AdjustRng(init_pattern_data_lotus + 0xFDA);
142 }
143 }
144 if (/*Entity_Record_Player::*/reroll_lotus_eater_stuff == -1) {
145 int index = find(data, {0xB8, 0xAB, 0xAA, 0xAA, 0xAA, 0x41, 0xC1, 0xE8});
146 if (index != -1) {
147 reroll_lotus_eater_stuff = i + index - 0x37;
148 AdjustRng(reroll_lotus_eater_stuff + 0x24);
149 AdjustRng(reroll_lotus_eater_stuff + 0x6B);
150 }
151 }
152 // These disable the random locations on timer panels, which would otherwise increment the RNG.
153 if (do_lotus_minutes == -1) {
154 int index = find(data, {0x0F, 0xBE, 0x6C, 0x08, 0xFF, 0x45});
155 if (index != -1) {
156 do_lotus_minutes = i + index - 0x2B;
157 _memory->WriteData<byte>({do_lotus_minutes + 0x43B}, {0x31, 0xC0, 0x90, 0x90, 0x90}); // xor eax, eax ;RNG returns 0
158 }
159 }
160 if (do_lotus_tenths == -1) {
161 int index = find(data, {0x00, 0x04, 0x00, 0x00, 0x41, 0x8D, 0x50, 0x09});
162 if (index != -1) {
163 do_lotus_tenths = i + index - 0x61;
164 _memory->WriteData<byte>({do_lotus_tenths + 0x103}, {0x31, 0xC0, 0x90, 0x90, 0x90}); // xor eax, eax ;RNG returns 0
165 }
166 }
167 if (do_lotus_eighths == -1) {
168 int index = find(data, {0x75, 0xF5, 0x0F, 0xBE, 0x44, 0x08, 0xFF});
169 if (index != -1) {
170 do_lotus_eighths = i + index - 0x39;
171 _memory->WriteData<byte>({do_lotus_eighths + 0x1E7}, {0x31, 0xC0, 0x90, 0x90, 0x90}); // xor eax, eax ;RNG returns 0
172 }
173 }
174} \ No newline at end of file
diff --git a/Source/ChallengeRandomizer.h b/Source/ChallengeRandomizer.h index 267c5cb..e642685 100644 --- a/Source/ChallengeRandomizer.h +++ b/Source/ChallengeRandomizer.h
@@ -7,6 +7,11 @@ public:
7 ChallengeRandomizer(const std::shared_ptr<Memory>& memory, int seed); 7 ChallengeRandomizer(const std::shared_ptr<Memory>& memory, int seed);
8 8
9private: 9private:
10 void HandleSigScans(int i, const std::vector<byte>& data);
11
10 void AdjustRng(int offset); 12 void AdjustRng(int offset);
11 std::shared_ptr<Memory> _memory; 13 std::shared_ptr<Memory> _memory;
14
15 int RNG_ADDR;
16 int RNG2_ADDR;
12}; 17};
diff --git a/Source/Memory.h b/Source/Memory.h index 278ce36..403b94a 100644 --- a/Source/Memory.h +++ b/Source/Memory.h
@@ -3,8 +3,8 @@
3#include <map> 3#include <map>
4#include <windows.h> 4#include <windows.h>
5 5
6#define GLOBALS 0x5B28C0 6// #define GLOBALS 0x5B28C0
7// #define GLOBALS 0x62A080 7#define GLOBALS 0x62A080
8 8
9// https://github.com/erayarslan/WriteProcessMemory-Example 9// https://github.com/erayarslan/WriteProcessMemory-Example
10// http://stackoverflow.com/q/32798185 10// http://stackoverflow.com/q/32798185
diff --git a/Source/Randomizer.cpp b/Source/Randomizer.cpp index 2f3e72a..48e9a4b 100644 --- a/Source/Randomizer.cpp +++ b/Source/Randomizer.cpp
@@ -89,6 +89,22 @@ void Randomizer::AdjustSpeed() {
89 _memory->WritePanelData<float>(0x09EEC, OPEN_RATE, {0.075f}); // 3x 89 _memory->WritePanelData<float>(0x09EEC, OPEN_RATE, {0.075f}); // 3x
90} 90}
91 91
92void Randomizer::RandomizeLasers() {
93 Randomize(lasers, SWAP::TARGETS);
94 // Read the target of keep front laser, and write it to keep back laser.
95 std::vector<int> keepFrontLaserTarget = _memory->ReadPanelData<int>(0x0360E, TARGET, 1);
96 _memory->WritePanelData<int>(0x03317, TARGET, keepFrontLaserTarget);
97}
98
99void Randomizer::PreventSnipes()
100{
101 // Distance-gate swamp snipe 1 to prevent RNG swamp snipe
102 _memory->WritePanelData<float>(0x17C05, MAX_BROADCAST_DISTANCE, {15.0});
103 // Distance-gate shadows laser to prevent sniping through the bars
104 _memory->WritePanelData<float>(0x19650, MAX_BROADCAST_DISTANCE, {2.5});
105}
106
107// Private methods
92void Randomizer::RandomizeTutorial() { 108void Randomizer::RandomizeTutorial() {
93 // Disable tutorial cursor speed modifications (not working?) 109 // Disable tutorial cursor speed modifications (not working?)
94 _memory->WritePanelData<float>(0x00295, CURSOR_SPEED_SCALE, {1.0}); 110 _memory->WritePanelData<float>(0x00295, CURSOR_SPEED_SCALE, {1.0});
@@ -130,8 +146,6 @@ void Randomizer::RandomizeKeep() {
130} 146}
131 147
132void Randomizer::RandomizeShadows() { 148void Randomizer::RandomizeShadows() {
133 // Distance-gate shadows laser to prevent sniping through the bars
134 _memory->WritePanelData<float>(0x19650, MAX_BROADCAST_DISTANCE, {2.5});
135 // Change the shadows tutorial cable to only activate avoid 149 // Change the shadows tutorial cable to only activate avoid
136 _memory->WritePanelData<int>(0x319A8, CABLE_TARGET_2, {0}); 150 _memory->WritePanelData<int>(0x319A8, CABLE_TARGET_2, {0});
137 // Change shadows avoid 8 to power shadows follow 151 // Change shadows avoid 8 to power shadows follow
@@ -182,13 +196,10 @@ void Randomizer::RandomizeJungle() {
182} 196}
183 197
184void Randomizer::RandomizeSwamp() { 198void Randomizer::RandomizeSwamp() {
185 // Distance-gate swamp snipe 1 to prevent RNG swamp snipe
186 _memory->WritePanelData<float>(0x17C05, MAX_BROADCAST_DISTANCE, {15.0});
187} 199}
188 200
189void Randomizer::RandomizeMountain() { 201void Randomizer::RandomizeMountain() {
190 // Randomize lasers & some of mountain 202 // Randomize multipanel
191 Randomize(lasers, SWAP::TARGETS);
192 Randomize(mountainMultipanel, SWAP::LINES); 203 Randomize(mountainMultipanel, SWAP::LINES);
193 204
194 // Randomize final pillars order 205 // Randomize final pillars order
@@ -210,14 +221,10 @@ void Randomizer::RandomizeMountain() {
210 // Turn on new starting panels 221 // Turn on new starting panels
211 _memory->WritePanelData<float>(pillars[randomOrder[0]], POWER, {1.0f, 1.0f}); 222 _memory->WritePanelData<float>(pillars[randomOrder[0]], POWER, {1.0f, 1.0f});
212 _memory->WritePanelData<float>(pillars[randomOrder[5]], POWER, {1.0f, 1.0f}); 223 _memory->WritePanelData<float>(pillars[randomOrder[5]], POWER, {1.0f, 1.0f});
213
214 // Read the target of keep front laser, and write it to keep back laser.
215 std::vector<int> keepFrontLaserTarget = _memory->ReadPanelData<int>(0x0360E, TARGET, 1);
216 _memory->WritePanelData<int>(0x03317, TARGET, keepFrontLaserTarget);
217} 224}
218 225
219void Randomizer::RandomizeChallenge() { 226void Randomizer::RandomizeChallenge() {
220 ChallengeRandomizer cr(_memory, Random::RandInt(1, 0x1000)); 227 ChallengeRandomizer cr(_memory, Random::RandInt(1, 0x7FFFFFFF)); // 0 will trigger an "RNG not initialized" block
221} 228}
222 229
223void Randomizer::RandomizeAudioLogs() { 230void Randomizer::RandomizeAudioLogs() {
diff --git a/Source/Randomizer.h b/Source/Randomizer.h index 1180d43..88afcc6 100644 --- a/Source/Randomizer.h +++ b/Source/Randomizer.h
@@ -8,6 +8,8 @@ public:
8 bool GameIsRandomized(); 8 bool GameIsRandomized();
9 9
10 void AdjustSpeed(); 10 void AdjustSpeed();
11 void RandomizeLasers();
12 void PreventSnipes();
11 13
12 void ClearOffsets() {_memory->ClearOffsets();} 14 void ClearOffsets() {_memory->ClearOffsets();}
13 15
@@ -19,7 +21,6 @@ public:
19 }; 21 };
20 22
21private: 23private:
22
23 int _lastRandomizedFrame = 1 << 30; 24 int _lastRandomizedFrame = 1 << 30;
24 void RandomizeTutorial(); 25 void RandomizeTutorial();
25 void RandomizeSymmetry(); 26 void RandomizeSymmetry();