about summary refs log tree commit diff stats
path: root/Source/ChallengeRandomizer.cpp
diff options
context:
space:
mode:
authorjbzdarkid <jbzdarkid@gmail.com>2018-11-18 14:34:34 -0800
committerjbzdarkid <jbzdarkid@gmail.com>2018-11-18 14:34:34 -0800
commitc10b73f30280e5dd758b77e2ef8e5a622ff3c876 (patch)
tree516924b39c353354d72a7020b1c3643a7f35f0b0 /Source/ChallengeRandomizer.cpp
parent145bfe30527ca604be7100f4515290152c8bc55b (diff)
downloadwitness-tutorializer-c10b73f30280e5dd758b77e2ef8e5a622ff3c876.tar.gz
witness-tutorializer-c10b73f30280e5dd758b77e2ef8e5a622ff3c876.tar.bz2
witness-tutorializer-c10b73f30280e5dd758b77e2ef8e5a622ff3c876.zip
Works, on old version
Diffstat (limited to 'Source/ChallengeRandomizer.cpp')
-rw-r--r--Source/ChallengeRandomizer.cpp145
1 files changed, 145 insertions, 0 deletions
diff --git a/Source/ChallengeRandomizer.cpp b/Source/ChallengeRandomizer.cpp new file mode 100644 index 0000000..b9b54e0 --- /dev/null +++ b/Source/ChallengeRandomizer.cpp
@@ -0,0 +1,145 @@
1#include "ChallengeRandomizer.h"
2#include <iostream>
3
4int find(const std::vector<byte> &data, const std::vector<byte>& search, size_t startIndex = 0) {
5 for (size_t i=startIndex; i<data.size() - search.size(); i++) {
6 bool match = true;
7 for (size_t j=0; j<search.size(); j++) {
8 if (data[i+j] == search[j]) {
9 continue;
10 }
11 match = false;
12 break;
13 }
14 if (match) return static_cast<int>(i);
15 }
16 return -1;
17}
18
19void ChallengeRandomizer::AdjustRng(int offset) {
20 int currentRng = _memory->ReadData<int>({offset}, 0x1)[0];
21 _memory->WriteData<int>({offset}, {currentRng + 0x20});
22}
23
24ChallengeRandomizer::ChallengeRandomizer(const std::shared_ptr<Memory>& memory, int seed) : _memory(memory)
25{
26 int RNG_ADDR = _memory->ReadData<int>({GLOBALS + 0x10}, 1)[0];
27 int RNG2_ADDR = _memory->ReadData<int>({GLOBALS + 0x30}, 1)[0];
28 _memory->WriteData<int>({GLOBALS + 0x30}, {RNG_ADDR + 4});
29 if (RNG2_ADDR == RNG_ADDR + 4) return; // Already applied hack
30
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;
42
43 for (int i=0; i<0x200000; i+=0x1000) {
44 std::vector<byte> data = _memory->ReadData<byte>({i}, 0x1100);
45 std::cout << data.size() << std::endl;
46
47 if (shuffle_integers == -1) {
48 int index = find(data, {0x48, 0x89, 0x5C, 0x24, 0x10, 0x56, 0x48, 0x83, 0xEC, 0x20, 0x48, 0x63, 0xDA, 0x48, 0x8B, 0xF1, 0x83, 0xFB, 0x01});
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, {0x8B, 0x80, 0xBC, 0x03, 0x00, 0x00, 0x89, 0x44, 0x24, 0x3C, 0x33, 0xC0});
56 if (index != -1) {
57 cut_random_edges = i + index - 0x1C;
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});
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});
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});
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});
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});
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});
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});
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});
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.
129 if (do_success_side_effects == -1) {
130 int index = find(data, {0x85, 0xC0, 0x7E, 0x2C, 0x48, 0x6B, 0xC8, 0x34});
131 if (index != -1) {
132 do_success_side_effects = i + index;
133 _memory->WriteData<byte>({do_success_side_effects}, {
134 0x8B, 0x0D, 0x00, 0x00, 0x00, 0x00, // mov ecx, [] ;This is going to be the address of the custom RNG
135 0x67, 0xC7, 0x01, 0x00, 0x00, 0x00, 0x00, // mov dword ptr ds:[ecx], 0x0 ;This is going to be the seed value
136 0x48, 0x83, 0xF8, 0x02, // cmp rax, 0x2 ;This is the short solve on the record player (which turns it off)
137 0x90, 0x90, 0x90 // nop nop nop
138 });
139 int target = (GLOBALS + 0x30) - (do_success_side_effects + 0x6); // +6 is for the length of the line
140 _memory->WriteData<int>({do_success_side_effects + 0x2}, {target});
141 _memory->WriteData<int>({do_success_side_effects + 0x9}, {seed});
142 }
143 }
144 }
145}