about summary refs log tree commit diff stats
path: root/Source
diff options
context:
space:
mode:
authorjbzdarkid <jbzdarkid@gmail.com>2019-11-16 21:17:48 -0800
committerjbzdarkid <jbzdarkid@gmail.com>2019-11-16 21:17:48 -0800
commit133975b5a2ceca273182829f2f11042a5276c2f0 (patch)
treea7e3b13ffd81484b41122acef5189f060cca365c /Source
parentfd2fa2211dc09c9030601fde1afd2f7823b22ed8 (diff)
downloadwitness-tutorializer-133975b5a2ceca273182829f2f11042a5276c2f0.tar.gz
witness-tutorializer-133975b5a2ceca273182829f2f11042a5276c2f0.tar.bz2
witness-tutorializer-133975b5a2ceca273182829f2f11042a5276c2f0.zip
Tabs -> spaces everywhere
Diffstat (limited to 'Source')
-rw-r--r--Source/ChallengeRandomizer.cpp182
-rw-r--r--Source/ChallengeRandomizer.h10
-rw-r--r--Source/Memory.cpp162
-rw-r--r--Source/Panels.h1362
-rw-r--r--Source/PuzzlerSerializer.h6
-rw-r--r--Source/Random.cpp6
-rw-r--r--Source/Random.h6
-rw-r--r--Source/Randomizer.cpp534
-rw-r--r--Source/Randomizer.h68
9 files changed, 1168 insertions, 1168 deletions
diff --git a/Source/ChallengeRandomizer.cpp b/Source/ChallengeRandomizer.cpp index de08885..e91e9ac 100644 --- a/Source/ChallengeRandomizer.cpp +++ b/Source/ChallengeRandomizer.cpp
@@ -3,106 +3,106 @@
3 3
4// Modify an opcode to use RNG2 instead of main RNG 4// Modify an opcode to use RNG2 instead of main RNG
5void ChallengeRandomizer::AdjustRng(int offset) { 5void ChallengeRandomizer::AdjustRng(int offset) {
6 int currentRng = _memory->ReadData<int>({offset}, 0x1)[0]; 6 int currentRng = _memory->ReadData<int>({offset}, 0x1)[0];
7 _memory->WriteData<int>({offset}, {currentRng + 0x20}); 7 _memory->WriteData<int>({offset}, {currentRng + 0x20});
8} 8}
9 9
10// Overwrite the pointer for the lightmap_generator (which is unused, afaict) to point to a secondary RNG. 10// Overwrite the pointer for the lightmap_generator (which is unused, afaict) to point to a secondary RNG.
11// Then, adjust all the RNG functions in challenge/doors to use this RNG. 11// Then, adjust all the RNG functions in challenge/doors to use this RNG.
12ChallengeRandomizer::ChallengeRandomizer(const std::shared_ptr<Memory>& memory, int seed) : _memory(memory) 12ChallengeRandomizer::ChallengeRandomizer(const std::shared_ptr<Memory>& memory, int seed) : _memory(memory)
13{ 13{
14 RNG_ADDR = _memory->ReadData<int>({GLOBALS + 0x10}, 1)[0]; 14 RNG_ADDR = _memory->ReadData<int>({GLOBALS + 0x10}, 1)[0];
15 RNG2_ADDR = _memory->ReadData<int>({GLOBALS + 0x30}, 1)[0]; 15 RNG2_ADDR = _memory->ReadData<int>({GLOBALS + 0x30}, 1)[0];
16 bool alreadyInjected = (RNG2_ADDR == RNG_ADDR + 4); 16 bool alreadyInjected = (RNG2_ADDR == RNG_ADDR + 4);
17 17
18 if (!alreadyInjected) _memory->WriteData<int>({GLOBALS + 0x30}, {RNG_ADDR + 4}); 18 if (!alreadyInjected) _memory->WriteData<int>({GLOBALS + 0x30}, {RNG_ADDR + 4});
19 _memory->WriteData<int>({GLOBALS + 0x30, 0}, {seed}); 19 _memory->WriteData<int>({GLOBALS + 0x30, 0}, {seed});
20 20
21 // do_success_side_effects 21 // do_success_side_effects
22 _memory->AddSigScan({0xFF, 0xC8, 0x99, 0x2B, 0xC2, 0xD1, 0xF8, 0x8B, 0xD0}, [&](int index) { 22 _memory->AddSigScan({0xFF, 0xC8, 0x99, 0x2B, 0xC2, 0xD1, 0xF8, 0x8B, 0xD0}, [&](int index) {
23 if (GLOBALS == 0x5B28C0) { // Version differences. 23 if (GLOBALS == 0x5B28C0) { // Version differences.
24 index += 0x3E; 24 index += 0x3E;
25 } else if (GLOBALS == 0x62D0A0) { 25 } else if (GLOBALS == 0x62D0A0) {
26 index += 0x42; 26 index += 0x42;
27 } 27 }
28 // Overwritten bytes start just after the movsxd rax, dword ptr ds:[rdi + 0x230] 28 // Overwritten bytes start just after the movsxd rax, dword ptr ds:[rdi + 0x230]
29 // aka test eax, eax; jle 2C; imul rcx, rax, 34 29 // aka test eax, eax; jle 2C; imul rcx, rax, 34
30 _memory->WriteData<byte>({index}, { 30 _memory->WriteData<byte>({index}, {
31 0x8B, 0x0D, 0x00, 0x00, 0x00, 0x00, // mov ecx, [0x00000000] ;This is going to be the address of the custom RNG 31 0x8B, 0x0D, 0x00, 0x00, 0x00, 0x00, // mov ecx, [0x00000000] ;This is going to be the address of the custom RNG
32 0x67, 0xC7, 0x01, 0x00, 0x00, 0x00, 0x00, // mov dword ptr ds:[ecx], 0x00000000 ;This is going to be the seed value 32 0x67, 0xC7, 0x01, 0x00, 0x00, 0x00, 0x00, // mov dword ptr ds:[ecx], 0x00000000 ;This is going to be the seed value
33 0x48, 0x83, 0xF8, 0x02, // cmp rax, 0x2 ;This is the short solve on the record player (which turns it off) 33 0x48, 0x83, 0xF8, 0x02, // cmp rax, 0x2 ;This is the short solve on the record player (which turns it off)
34 0x90, 0x90, 0x90 // nop nop nop 34 0x90, 0x90, 0x90 // nop nop nop
35 }); 35 });
36 int target = (GLOBALS + 0x30) - (index + 0x6); // +6 is for the length of the line 36 int target = (GLOBALS + 0x30) - (index + 0x6); // +6 is for the length of the line
37 _memory->WriteData<int>({index + 0x2}, {target}); 37 _memory->WriteData<int>({index + 0x2}, {target});
38 _memory->WriteData<int>({index + 0x9}, {seed}); // Because we're resetting seed every challenge, we need to run this injection every time. 38 _memory->WriteData<int>({index + 0x9}, {seed}); // Because we're resetting seed every challenge, we need to run this injection every time.
39 }); 39 });
40 40
41 if (!alreadyInjected) { 41 if (!alreadyInjected) {
42 // shuffle_integers 42 // shuffle_integers
43 _memory->AddSigScan({0x48, 0x89, 0x5C, 0x24, 0x10, 0x56, 0x48, 0x83, 0xEC, 0x20, 0x48, 0x63, 0xDA, 0x48, 0x8B, 0xF1, 0x83, 0xFB, 0x01}, [&](int index) { 43 _memory->AddSigScan({0x48, 0x89, 0x5C, 0x24, 0x10, 0x56, 0x48, 0x83, 0xEC, 0x20, 0x48, 0x63, 0xDA, 0x48, 0x8B, 0xF1, 0x83, 0xFB, 0x01}, [&](int index) {
44 AdjustRng(index + 0x23); 44 AdjustRng(index + 0x23);
45 }); 45 });
46 // shuffle<int> 46 // shuffle<int>
47 _memory->AddSigScan({0x33, 0xF6, 0x48, 0x8B, 0xD9, 0x39, 0x31, 0x7E, 0x51}, [&](int index) { 47 _memory->AddSigScan({0x33, 0xF6, 0x48, 0x8B, 0xD9, 0x39, 0x31, 0x7E, 0x51}, [&](int index) {
48 AdjustRng(index - 0x4); 48 AdjustRng(index - 0x4);
49 }); 49 });
50 // cut_random_edges 50 // cut_random_edges
51 _memory->AddSigScan({0x89, 0x44, 0x24, 0x3C, 0x33, 0xC0, 0x85, 0xC0, 0x75, 0xFA}, [&](int index) { 51 _memory->AddSigScan({0x89, 0x44, 0x24, 0x3C, 0x33, 0xC0, 0x85, 0xC0, 0x75, 0xFA}, [&](int index) {
52 AdjustRng(index + 0x3B); 52 AdjustRng(index + 0x3B);
53 }); 53 });
54 // get_empty_decoration_slot 54 // get_empty_decoration_slot
55 _memory->AddSigScan({0x42, 0x83, 0x3C, 0x80, 0x00, 0x75, 0xDF}, [&](int index) { 55 _memory->AddSigScan({0x42, 0x83, 0x3C, 0x80, 0x00, 0x75, 0xDF}, [&](int index) {
56 AdjustRng(index - 0x17); 56 AdjustRng(index - 0x17);
57 }); 57 });
58 // get_empty_dot_spot 58 // get_empty_dot_spot
59 _memory->AddSigScan({0xF7, 0xF3, 0x85, 0xD2, 0x74, 0xEC}, [&](int index) { 59 _memory->AddSigScan({0xF7, 0xF3, 0x85, 0xD2, 0x74, 0xEC}, [&](int index) {
60 AdjustRng(index - 0xB); 60 AdjustRng(index - 0xB);
61 }); 61 });
62 // add_exactly_this_many_bisection_dots 62 // add_exactly_this_many_bisection_dots
63 _memory->AddSigScan({0x48, 0x8B, 0xB4, 0x24, 0xB8, 0x00, 0x00, 0x00, 0x48, 0x8B, 0xBC, 0x24, 0xB0, 0x00, 0x00, 0x00}, [&](int index) { 63 _memory->AddSigScan({0x48, 0x8B, 0xB4, 0x24, 0xB8, 0x00, 0x00, 0x00, 0x48, 0x8B, 0xBC, 0x24, 0xB0, 0x00, 0x00, 0x00}, [&](int index) {
64 AdjustRng(index - 0x4); 64 AdjustRng(index - 0x4);
65 }); 65 });
66 // make_a_shaper 66 // make_a_shaper
67 _memory->AddSigScan({0xF7, 0xE3, 0xD1, 0xEA, 0x8D, 0x0C, 0x52}, [&](int index) { 67 _memory->AddSigScan({0xF7, 0xE3, 0xD1, 0xEA, 0x8D, 0x0C, 0x52}, [&](int index) {
68 AdjustRng(index - 0x10); 68 AdjustRng(index - 0x10);
69 AdjustRng(index + 0x1C); 69 AdjustRng(index + 0x1C);
70 AdjustRng(index + 0x49); 70 AdjustRng(index + 0x49);
71 }); 71 });
72 // Entity_Machine_Panel::init_pattern_data_lotus 72 // Entity_Machine_Panel::init_pattern_data_lotus
73 _memory->AddSigScan({0x40, 0x55, 0x56, 0x48, 0x8D, 0x6C, 0x24, 0xB1}, [&](int index) { 73 _memory->AddSigScan({0x40, 0x55, 0x56, 0x48, 0x8D, 0x6C, 0x24, 0xB1}, [&](int index) {
74 AdjustRng(index + 0x433); 74 AdjustRng(index + 0x433);
75 AdjustRng(index + 0x45B); 75 AdjustRng(index + 0x45B);
76 AdjustRng(index + 0x5A7); 76 AdjustRng(index + 0x5A7);
77 AdjustRng(index + 0x5D6); 77 AdjustRng(index + 0x5D6);
78 AdjustRng(index + 0x6F6); 78 AdjustRng(index + 0x6F6);
79 AdjustRng(index + 0xD17); 79 AdjustRng(index + 0xD17);
80 AdjustRng(index + 0xFDA); 80 AdjustRng(index + 0xFDA);
81 }); 81 });
82 // Entity_Record_Player::reroll_lotus_eater_stuff 82 // Entity_Record_Player::reroll_lotus_eater_stuff
83 _memory->AddSigScan({0xB8, 0xAB, 0xAA, 0xAA, 0xAA, 0x41, 0xC1, 0xE8}, [&](int index) { 83 _memory->AddSigScan({0xB8, 0xAB, 0xAA, 0xAA, 0xAA, 0x41, 0xC1, 0xE8}, [&](int index) {
84 AdjustRng(index - 0x13); 84 AdjustRng(index - 0x13);
85 AdjustRng(index + 0x34); 85 AdjustRng(index + 0x34);
86 }); 86 });
87 87
88 // These disable the random locations on timer panels, which would otherwise increment the RNG. 88 // These disable the random locations on timer panels, which would otherwise increment the RNG.
89 // I'm writing 31 C0 (xor eax, eax), then 3 NOPs, which pretends the RNG returns 0. 89 // I'm writing 31 C0 (xor eax, eax), then 3 NOPs, which pretends the RNG returns 0.
90 // do_lotus_minutes 90 // do_lotus_minutes
91 _memory->AddSigScan({0x0F, 0xBE, 0x6C, 0x08, 0xFF, 0x45}, [&](int index) { 91 _memory->AddSigScan({0x0F, 0xBE, 0x6C, 0x08, 0xFF, 0x45}, [&](int index) {
92 _memory->WriteData<byte>({index + 0x410}, {0x31, 0xC0, 0x90, 0x90, 0x90}); 92 _memory->WriteData<byte>({index + 0x410}, {0x31, 0xC0, 0x90, 0x90, 0x90});
93 }); 93 });
94 // do_lotus_tenths 94 // do_lotus_tenths
95 _memory->AddSigScan({0x00, 0x04, 0x00, 0x00, 0x41, 0x8D, 0x50, 0x09}, [&](int index) { 95 _memory->AddSigScan({0x00, 0x04, 0x00, 0x00, 0x41, 0x8D, 0x50, 0x09}, [&](int index) {
96 _memory->WriteData<byte>({index + 0xA2}, {0x31, 0xC0, 0x90, 0x90, 0x90}); 96 _memory->WriteData<byte>({index + 0xA2}, {0x31, 0xC0, 0x90, 0x90, 0x90});
97 }); 97 });
98 // do_lotus_eighths 98 // do_lotus_eighths
99 _memory->AddSigScan({0x75, 0xF5, 0x0F, 0xBE, 0x44, 0x08, 0xFF}, [&](int index) { 99 _memory->AddSigScan({0x75, 0xF5, 0x0F, 0xBE, 0x44, 0x08, 0xFF}, [&](int index) {
100 _memory->WriteData<byte>({index + 0x1AE}, {0x31, 0xC0, 0x90, 0x90, 0x90}); 100 _memory->WriteData<byte>({index + 0x1AE}, {0x31, 0xC0, 0x90, 0x90, 0x90});
101 }); 101 });
102 } 102 }
103 103
104 int failed = _memory->ExecuteSigScans(); 104 int failed = _memory->ExecuteSigScans();
105 if (failed != 0) { 105 if (failed != 0) {
106 std::cout << "Failed " << failed << " sigscans"; 106 std::cout << "Failed " << failed << " sigscans";
107 } 107 }
108} 108}
diff --git a/Source/ChallengeRandomizer.h b/Source/ChallengeRandomizer.h index 10944cd..fb0338a 100644 --- a/Source/ChallengeRandomizer.h +++ b/Source/ChallengeRandomizer.h
@@ -4,12 +4,12 @@
4 4
5class ChallengeRandomizer { 5class ChallengeRandomizer {
6public: 6public:
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 AdjustRng(int offset); 10 void AdjustRng(int offset);
11 std::shared_ptr<Memory> _memory; 11 std::shared_ptr<Memory> _memory;
12 12
13 int RNG_ADDR; 13 int RNG_ADDR;
14 int RNG2_ADDR; 14 int RNG2_ADDR;
15}; 15};
diff --git a/Source/Memory.cpp b/Source/Memory.cpp index d90c402..26ef7e4 100644 --- a/Source/Memory.cpp +++ b/Source/Memory.cpp
@@ -73,124 +73,124 @@ void Memory::Heartbeat(HWND window) {
73 73
74[[nodiscard]] 74[[nodiscard]]
75bool Memory::Initialize() { 75bool Memory::Initialize() {
76 // First, get the handle of the process 76 // First, get the handle of the process
77 PROCESSENTRY32W entry; 77 PROCESSENTRY32W entry;
78 entry.dwSize = sizeof(entry); 78 entry.dwSize = sizeof(entry);
79 HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 79 HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
80 while (Process32NextW(snapshot, &entry)) { 80 while (Process32NextW(snapshot, &entry)) {
81 if (_processName == entry.szExeFile) { 81 if (_processName == entry.szExeFile) {
82 _handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID); 82 _handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID);
83 break; 83 break;
84 } 84 }
85 } 85 }
86 if (!_handle) { 86 if (!_handle) {
87 std::cerr << "Couldn't find " << _processName.c_str() << ", is it open?" << std::endl; 87 std::cerr << "Couldn't find " << _processName.c_str() << ", is it open?" << std::endl;
88 return false; 88 return false;
89 } 89 }
90 90
91 // Next, get the process base address 91 // Next, get the process base address
92 DWORD numModules; 92 DWORD numModules;
93 std::vector<HMODULE> moduleList(1024); 93 std::vector<HMODULE> moduleList(1024);
94 EnumProcessModulesEx(_handle, &moduleList[0], static_cast<DWORD>(moduleList.size()), &numModules, 3); 94 EnumProcessModulesEx(_handle, &moduleList[0], static_cast<DWORD>(moduleList.size()), &numModules, 3);
95 95
96 std::wstring name(64, '\0'); 96 std::wstring name(64, '\0');
97 for (DWORD i = 0; i < numModules / sizeof(HMODULE); i++) { 97 for (DWORD i = 0; i < numModules / sizeof(HMODULE); i++) {
98 int length = GetModuleBaseNameW(_handle, moduleList[i], &name[0], static_cast<DWORD>(name.size())); 98 int length = GetModuleBaseNameW(_handle, moduleList[i], &name[0], static_cast<DWORD>(name.size()));
99 name.resize(length); 99 name.resize(length);
100 if (_processName == name) { 100 if (_processName == name) {
101 _baseAddress = (uintptr_t)moduleList[i]; 101 _baseAddress = (uintptr_t)moduleList[i];
102 break; 102 break;
103 } 103 }
104 } 104 }
105 if (_baseAddress == 0) { 105 if (_baseAddress == 0) {
106 std::cerr << "Couldn't locate base address" << std::endl; 106 std::cerr << "Couldn't locate base address" << std::endl;
107 return false; 107 return false;
108 } 108 }
109 109
110 return true; 110 return true;
111} 111}
112 112
113void Memory::AddSigScan(const std::vector<byte>& scanBytes, const std::function<void(int index)>& scanFunc) 113void Memory::AddSigScan(const std::vector<byte>& scanBytes, const std::function<void(int index)>& scanFunc)
114{ 114{
115 _sigScans[scanBytes] = {scanFunc, false}; 115 _sigScans[scanBytes] = {scanFunc, false};
116} 116}
117 117
118int find(const std::vector<byte> &data, const std::vector<byte>& search, size_t startIndex = 0) { 118int find(const std::vector<byte> &data, const std::vector<byte>& search, size_t startIndex = 0) {
119 for (size_t i=startIndex; i<data.size() - search.size(); i++) { 119 for (size_t i=startIndex; i<data.size() - search.size(); i++) {
120 bool match = true; 120 bool match = true;
121 for (size_t j=0; j<search.size(); j++) { 121 for (size_t j=0; j<search.size(); j++) {
122 if (data[i+j] == search[j]) { 122 if (data[i+j] == search[j]) {
123 continue; 123 continue;
124 } 124 }
125 match = false; 125 match = false;
126 break; 126 break;
127 } 127 }
128 if (match) return static_cast<int>(i); 128 if (match) return static_cast<int>(i);
129 } 129 }
130 return -1; 130 return -1;
131} 131}
132 132
133int Memory::ExecuteSigScans() 133int Memory::ExecuteSigScans()
134{ 134{
135 for (int i=0; i<0x200000; i+=0x1000) { 135 for (int i=0; i<0x200000; i+=0x1000) {
136 std::vector<byte> data = ReadData<byte>({i}, 0x1100); 136 std::vector<byte> data = ReadData<byte>({i}, 0x1100);
137 137
138 for (auto& [scanBytes, sigScan] : _sigScans) { 138 for (auto& [scanBytes, sigScan] : _sigScans) {
139 if (sigScan.found) continue; 139 if (sigScan.found) continue;
140 int index = find(data, scanBytes); 140 int index = find(data, scanBytes);
141 if (index == -1) continue; 141 if (index == -1) continue;
142 sigScan.scanFunc(i + index); 142 sigScan.scanFunc(i + index);
143 sigScan.found = true; 143 sigScan.found = true;
144 } 144 }
145 } 145 }
146 146
147 int notFound = 0; 147 int notFound = 0;
148 for (auto it : _sigScans) { 148 for (auto it : _sigScans) {
149 if (it.second.found == false) notFound++; 149 if (it.second.found == false) notFound++;
150 } 150 }
151 return notFound; 151 return notFound;
152} 152}
153 153
154void Memory::ThrowError() { 154void Memory::ThrowError() {
155 std::wstring message(256, '\0'); 155 std::wstring message(256, '\0');
156 DWORD error = GetLastError(); 156 DWORD error = GetLastError();
157 int length = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, error, 1024, &message[0], static_cast<DWORD>(message.size()), nullptr); 157 int length = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, error, 1024, &message[0], static_cast<DWORD>(message.size()), nullptr);
158 message.resize(length); 158 message.resize(length);
159#ifndef NDEBUG 159#ifndef NDEBUG
160 MessageBox(NULL, message.c_str(), L"Please tell darkid about this", MB_OK); 160 MessageBox(NULL, message.c_str(), L"Please tell darkid about this", MB_OK);
161#endif 161#endif
162} 162}
163 163
164void* Memory::ComputeOffset(std::vector<int> offsets) { 164void* Memory::ComputeOffset(std::vector<int> offsets) {
165 // Leave off the last offset, since it will be either read/write, and may not be of type uintptr_t. 165 // Leave off the last offset, since it will be either read/write, and may not be of type uintptr_t.
166 int final_offset = offsets.back(); 166 int final_offset = offsets.back();
167 offsets.pop_back(); 167 offsets.pop_back();
168 168
169 uintptr_t cumulativeAddress = _baseAddress; 169 uintptr_t cumulativeAddress = _baseAddress;
170 for (const int offset : offsets) { 170 for (const int offset : offsets) {
171 cumulativeAddress += offset; 171 cumulativeAddress += offset;
172 172
173 const auto search = _computedAddresses.find(cumulativeAddress); 173 const auto search = _computedAddresses.find(cumulativeAddress);
174 // This is an issue with re-randomization. Always. Just disable it in debug mode! 174 // This is an issue with re-randomization. Always. Just disable it in debug mode!
175#ifdef NDEBUG 175#ifdef NDEBUG
176 if (search == std::end(_computedAddresses)) { 176 if (search == std::end(_computedAddresses)) {
177#endif 177#endif
178 // If the address is not yet computed, then compute it. 178 // If the address is not yet computed, then compute it.
179 uintptr_t computedAddress = 0; 179 uintptr_t computedAddress = 0;
180 if (bool result = !ReadProcessMemory(_handle, reinterpret_cast<LPVOID>(cumulativeAddress), &computedAddress, sizeof(uintptr_t), NULL)) { 180 if (bool result = !ReadProcessMemory(_handle, reinterpret_cast<LPVOID>(cumulativeAddress), &computedAddress, sizeof(uintptr_t), NULL)) {
181 ThrowError(); 181 ThrowError();
182 } 182 }
183 if (computedAddress == 0) { // Attempting to dereference a nullptr 183 if (computedAddress == 0) { // Attempting to dereference a nullptr
184 ThrowError(); 184 ThrowError();
185 } 185 }
186 _computedAddresses[cumulativeAddress] = computedAddress; 186 _computedAddresses[cumulativeAddress] = computedAddress;
187#ifdef NDEBUG 187#ifdef NDEBUG
188 } 188 }
189#endif 189#endif
190 190
191 cumulativeAddress = _computedAddresses[cumulativeAddress]; 191 cumulativeAddress = _computedAddresses[cumulativeAddress];
192 } 192 }
193 return reinterpret_cast<void*>(cumulativeAddress + final_offset); 193 return reinterpret_cast<void*>(cumulativeAddress + final_offset);
194} 194}
195 195
196uintptr_t Memory::Allocate(size_t bytes) { 196uintptr_t Memory::Allocate(size_t bytes) {
diff --git a/Source/Panels.h b/Source/Panels.h index 7959e21..2c7c075 100644 --- a/Source/Panels.h +++ b/Source/Panels.h
@@ -3,752 +3,752 @@
3 3
4// Some of these (the puzzle ones) are duplicated elsewhere 4// Some of these (the puzzle ones) are duplicated elsewhere
5std::vector<int> lasers = { 5std::vector<int> lasers = {
6 0x0360D, // Symmetry 6 0x0360D, // Symmetry
7 0x03615, // Swamp 7 0x03615, // Swamp
8 0x09DE0, // Bunker 8 0x09DE0, // Bunker
9 0x17CA4, // Monastery 9 0x17CA4, // Monastery
10 0x032F5, // Town 10 0x032F5, // Town
11 0x03613, // Treehouse 11 0x03613, // Treehouse
12 0x0360E, // Keep Front Laser 12 0x0360E, // Keep Front Laser
13// 0x03317, // Keep Back Laser 13// 0x03317, // Keep Back Laser
14// 0x03608, // Desert 14// 0x03608, // Desert
15 0x03612, // Quarry 15 0x03612, // Quarry
16 0x03616, // Jungle 16 0x03616, // Jungle
17 0x19650, // Shadows 17 0x19650, // Shadows
18}; 18};
19 19
20// Note: Some of these (non-controls) are duplicated elsewhere 20// Note: Some of these (non-controls) are duplicated elsewhere
21// TODO: Gave up 21// TODO: Gave up
22std::vector<int> leftRightPanels = { 22std::vector<int> leftRightPanels = {
23 0x01A54, // Glass Factory Entry 23 0x01A54, // Glass Factory Entry
24 0x00086, // Glass Factory Vertical Symmetry 1 24 0x00086, // Glass Factory Vertical Symmetry 1
25 0x00087, // Glass Factory Vertical Symmetry 2 25 0x00087, // Glass Factory Vertical Symmetry 2
26 0x00059, // Glass Factory Vertical Symmetry 3 26 0x00059, // Glass Factory Vertical Symmetry 3
27 0x00062, // Glass Factory Vertical Symmetry 4 27 0x00062, // Glass Factory Vertical Symmetry 4
28 0x00025, // Symmetry Island Black Dots 4 28 0x00025, // Symmetry Island Black Dots 4
29 0x00026, // Symmetry Island Black Dots 5 29 0x00026, // Symmetry Island Black Dots 5
30 0x00072, // Symmetry Island Fading Lines 3 30 0x00072, // Symmetry Island Fading Lines 3
31 31
32 0x17D02, // Town Windmill Control 32 0x17D02, // Town Windmill Control
33}; 33};
34 34
35// Note: Some of these (non-controls) are duplicated elsewhere 35// Note: Some of these (non-controls) are duplicated elsewhere
36std::vector<int> upDownPanels = { 36std::vector<int> upDownPanels = {
37 0x0008D, // Glass Factory Rotational Symmetry 1 37 0x0008D, // Glass Factory Rotational Symmetry 1
38 0x00081, // Glass Factory Rotational Symmetry 2 38 0x00081, // Glass Factory Rotational Symmetry 2
39 0x00083, // Glass Factory Rotational Symmetry 3 39 0x00083, // Glass Factory Rotational Symmetry 3
40 0x00084, // Glass Factory Melting 1 40 0x00084, // Glass Factory Melting 1
41 0x00070, // Symmetry Island Fading Lines 5 41 0x00070, // Symmetry Island Fading Lines 5
42 0x01E5A, // Mill Entry Door Left 42 0x01E5A, // Mill Entry Door Left
43 0x28AC7, // Town Blue 1 43 0x28AC7, // Town Blue 1
44 0x28AC8, // Town Blue 2 44 0x28AC8, // Town Blue 2
45 0x28ACA, // Town Blue 3 45 0x28ACA, // Town Blue 3
46 0x28ACB, // Town Blue 4 46 0x28ACB, // Town Blue 4
47 0x28ACC, // Town Blue 5 47 0x28ACC, // Town Blue 5
48 0x00029, // UTM Invisible Dots Symmetry 3 48 0x00029, // UTM Invisible Dots Symmetry 3
49 0x288AA, // UTM Perspective 4 49 0x288AA, // UTM Perspective 4
50 50
51 0x0A3B5, // Tutorial Back Left 51 0x0A3B5, // Tutorial Back Left
52 0x17CC4, // Mill Elevator Control 52 0x17CC4, // Mill Elevator Control
53// 0x335AB, // UTM In Elevator Control 53// 0x335AB, // UTM In Elevator Control
54// 0x3369D, // UTM Lower Elevator Control 54// 0x3369D, // UTM Lower Elevator Control
55// 0x335AC, // UTM Upper Elevator Control 55// 0x335AC, // UTM Upper Elevator Control
56}; 56};
57 57
58// Note: Some of these (non-controls) are duplicated elsewhere 58// Note: Some of these (non-controls) are duplicated elsewhere
59std::vector<int> leftForwardRightPanels = { 59std::vector<int> leftForwardRightPanels = {
60 0x00075, // Symmetry Island Colored Dots 3 60 0x00075, // Symmetry Island Colored Dots 3
61 0x288EA, // UTM Perspective 1 61 0x288EA, // UTM Perspective 1
62 0x288FC, // UTM Perspective 2 62 0x288FC, // UTM Perspective 2
63 0x289E7, // UTM Perspective 3 63 0x289E7, // UTM Perspective 3
64 64
65 0x17DD1, // Treehouse Left Orange 9 65 0x17DD1, // Treehouse Left Orange 9
66 0x17CE3, // Treehouse Right Orange 4 66 0x17CE3, // Treehouse Right Orange 4
67 0x17DB7, // Treehouse Right Orange 10 67 0x17DB7, // Treehouse Right Orange 10
68 0x17E52, // Treehouse Green 4 68 0x17E52, // Treehouse Green 4
69}; 69};
70 70
71std::vector<int> pillars = { 71std::vector<int> pillars = {
72 0x0383D, // Mountain 3 Left Pillar 1 72 0x0383D, // Mountain 3 Left Pillar 1
73 0x0383F, // Mountain 3 Left Pillar 2 73 0x0383F, // Mountain 3 Left Pillar 2
74 0x03859, // Mountain 3 Left Pillar 3 74 0x03859, // Mountain 3 Left Pillar 3
75 0x339BB, // Mountain 3 Left Pillar 4 75 0x339BB, // Mountain 3 Left Pillar 4
76 0x3C113, // Mountain 3 Left Open Door 76 0x3C113, // Mountain 3 Left Open Door
77 0x0383A, // Mountain 3 Right Pillar 1 77 0x0383A, // Mountain 3 Right Pillar 1
78 0x09E56, // Mountain 3 Right Pillar 2 78 0x09E56, // Mountain 3 Right Pillar 2
79 0x09E5A, // Mountain 3 Right Pillar 3 79 0x09E5A, // Mountain 3 Right Pillar 3
80 0x33961, // Mountain 3 Right Pillar 4 80 0x33961, // Mountain 3 Right Pillar 4
81 0x3C114, // Mountain 3 Right Open Door 81 0x3C114, // Mountain 3 Right Open Door
82// 0x09DD5, // UTM Challenge Pillar 82// 0x09DD5, // UTM Challenge Pillar
83}; 83};
84 84
85std::vector<int> challengePanels = { 85std::vector<int> challengePanels = {
86 0x0A332, // Challenge Record Start 86 0x0A332, // Challenge Record Start
87 0x0088E, // Challenge Easy Maze 87 0x0088E, // Challenge Easy Maze
88 0x00BAF, // Challenge Hard Maze 88 0x00BAF, // Challenge Hard Maze
89 0x00BF3, // Challenge Stones Maze 89 0x00BF3, // Challenge Stones Maze
90 0x00C09, // Challenge Pedestal 90 0x00C09, // Challenge Pedestal
91 0x0051F, // Challenge Column Bottom Left 91 0x0051F, // Challenge Column Bottom Left
92 0x00524, // Challenge Column Top Right 92 0x00524, // Challenge Column Top Right
93 0x00CDB, // Challenge Column Top Left 93 0x00CDB, // Challenge Column Top Left
94 0x00CD4, // Challenge Column Far Panel 94 0x00CD4, // Challenge Column Far Panel
95 0x00C80, // Challenge Triple 1 Left 95 0x00C80, // Challenge Triple 1 Left
96 0x00CA1, // Challenge Triple 1 Center 96 0x00CA1, // Challenge Triple 1 Center
97 0x00CB9, // Challenge Triple 1 Right 97 0x00CB9, // Challenge Triple 1 Right
98 0x00C22, // Challenge Triple 2 Left 98 0x00C22, // Challenge Triple 2 Left
99 0x00C59, // Challenge Triple 2 Center 99 0x00C59, // Challenge Triple 2 Center
100 0x00C68, // Challenge Triple 2 Right 100 0x00C68, // Challenge Triple 2 Right
101// 0x04CB3, // Challenge Left Timer 101// 0x04CB3, // Challenge Left Timer
102// 0x04CB5, // Challenge Middle Timer 102// 0x04CB5, // Challenge Middle Timer
103// 0x04CB6, // Challenge Right Timer 103// 0x04CB6, // Challenge Right Timer
104 0x034EC, // Challenge Triangle 104 0x034EC, // Challenge Triangle
105 0x034F4, // Challenge Triangle 105 0x034F4, // Challenge Triangle
106 0x1C31A, // Challenge Left Pillar 106 0x1C31A, // Challenge Left Pillar
107 0x1C319, // Challenge Right Pillar 107 0x1C319, // Challenge Right Pillar
108// 0x0356B, // Challenge Vault Box 108// 0x0356B, // Challenge Vault Box
109}; 109};
110 110
111std::vector<int> mountainMultipanel = { 111std::vector<int> mountainMultipanel = {
112 0x09FCC, // Mountain 2 Multipanel 1 112 0x09FCC, // Mountain 2 Multipanel 1
113 0x09FCE, // Mountain 2 Multipanel 2 113 0x09FCE, // Mountain 2 Multipanel 2
114 0x09FCF, // Mountain 2 Multipanel 3 114 0x09FCF, // Mountain 2 Multipanel 3
115 0x09FD0, // Mountain 2 Multipanel 4 115 0x09FD0, // Mountain 2 Multipanel 4
116 0x09FD1, // Mountain 2 Multipanel 5 116 0x09FD1, // Mountain 2 Multipanel 5
117 0x09FD2, // Mountain 2 Multipanel 6 117 0x09FD2, // Mountain 2 Multipanel 6
118}; 118};
119 119
120std::vector<int> squarePanels = { 120std::vector<int> squarePanels = {
121 0x00064, // Tutorial Straight 121 0x00064, // Tutorial Straight
122 0x00182, // Tutorial Bend 122 0x00182, // Tutorial Bend
123 0x0A3B2, // Tutorial Back Right 123 0x0A3B2, // Tutorial Back Right
124 0x00295, // Tutorial Center Left 124 0x00295, // Tutorial Center Left
125 0x00293, // Tutorial Front Center 125 0x00293, // Tutorial Front Center
126 0x002C2, // Tutorial Front Left 126 0x002C2, // Tutorial Front Left
127 0x0005D, // Outside Tutorial Dots Tutorial 1 127 0x0005D, // Outside Tutorial Dots Tutorial 1
128 0x0005E, // Outside Tutorial Dots Tutorial 2 128 0x0005E, // Outside Tutorial Dots Tutorial 2
129 0x0005F, // Outside Tutorial Dots Tutorial 3 129 0x0005F, // Outside Tutorial Dots Tutorial 3
130 0x00060, // Outside Tutorial Dots Tutorial 4 130 0x00060, // Outside Tutorial Dots Tutorial 4
131 0x00061, // Outside Tutorial Dots Tutorial 5 131 0x00061, // Outside Tutorial Dots Tutorial 5
132 0x018AF, // Outside Tutorial Stones Tutorial 1 132 0x018AF, // Outside Tutorial Stones Tutorial 1
133 0x0001B, // Outside Tutorial Stones Tutorial 2 133 0x0001B, // Outside Tutorial Stones Tutorial 2
134 0x012C9, // Outside Tutorial Stones Tutorial 3 134 0x012C9, // Outside Tutorial Stones Tutorial 3
135 0x0001C, // Outside Tutorial Stones Tutorial 4 135 0x0001C, // Outside Tutorial Stones Tutorial 4
136 0x0001D, // Outside Tutorial Stones Tutorial 5 136 0x0001D, // Outside Tutorial Stones Tutorial 5
137 0x0001E, // Outside Tutorial Stones Tutorial 6 137 0x0001E, // Outside Tutorial Stones Tutorial 6
138 0x0001F, // Outside Tutorial Stones Tutorial 7 138 0x0001F, // Outside Tutorial Stones Tutorial 7
139 0x00020, // Outside Tutorial Stones Tutorial 8 139 0x00020, // Outside Tutorial Stones Tutorial 8
140 0x00021, // Outside Tutorial Stones Tutorial 9 140 0x00021, // Outside Tutorial Stones Tutorial 9
141 0x033D4, // Outside Tutorial Vault 141 0x033D4, // Outside Tutorial Vault
142 0x0A171, // Tutorial Optional Door 1 142 0x0A171, // Tutorial Optional Door 1
143 0x04CA4, // Tutorial Optional Door 2 143 0x04CA4, // Tutorial Optional Door 2
144 0x17CFB, // Outside Tutorial Discard 144 0x17CFB, // Outside Tutorial Discard
145 0x3C12B, // Glass Factory Discard 145 0x3C12B, // Glass Factory Discard
146 0x01A54, // Glass Factory Entry 146 0x01A54, // Glass Factory Entry
147 0x00086, // Glass Factory Vertical Symmetry 1 147 0x00086, // Glass Factory Vertical Symmetry 1
148 0x00087, // Glass Factory Vertical Symmetry 2 148 0x00087, // Glass Factory Vertical Symmetry 2
149 0x00059, // Glass Factory Vertical Symmetry 3 149 0x00059, // Glass Factory Vertical Symmetry 3
150 0x00062, // Glass Factory Vertical Symmetry 4 150 0x00062, // Glass Factory Vertical Symmetry 4
151 0x0008D, // Glass Factory Rotational Symmetry 1 151 0x0008D, // Glass Factory Rotational Symmetry 1
152 0x00081, // Glass Factory Rotational Symmetry 2 152 0x00081, // Glass Factory Rotational Symmetry 2
153 0x00083, // Glass Factory Rotational Symmetry 3 153 0x00083, // Glass Factory Rotational Symmetry 3
154 0x00084, // Glass Factory Melting 1 154 0x00084, // Glass Factory Melting 1
155 0x00082, // Glass Factory Melting 2 155 0x00082, // Glass Factory Melting 2
156 0x0343A, // Glass Factory Melting 3 156 0x0343A, // Glass Factory Melting 3
157 0x000B0, // Symmetry Island Door 1 157 0x000B0, // Symmetry Island Door 1
158 0x00022, // Symmetry Island Black Dots 1 158 0x00022, // Symmetry Island Black Dots 1
159 0x00023, // Symmetry Island Black Dots 2 159 0x00023, // Symmetry Island Black Dots 2
160 0x00024, // Symmetry Island Black Dots 3 160 0x00024, // Symmetry Island Black Dots 3
161 0x00025, // Symmetry Island Black Dots 4 161 0x00025, // Symmetry Island Black Dots 4
162 0x00026, // Symmetry Island Black Dots 5 162 0x00026, // Symmetry Island Black Dots 5
163 0x0007C, // Symmetry Island Colored Dots 1 163 0x0007C, // Symmetry Island Colored Dots 1
164 0x0007E, // Symmetry Island Colored Dots 2 164 0x0007E, // Symmetry Island Colored Dots 2
165 0x00075, // Symmetry Island Colored Dots 3 165 0x00075, // Symmetry Island Colored Dots 3
166 0x00073, // Symmetry Island Colored Dots 4 166 0x00073, // Symmetry Island Colored Dots 4
167 0x00077, // Symmetry Island Colored Dots 5 167 0x00077, // Symmetry Island Colored Dots 5
168 0x00079, // Symmetry Island Colored Dots 6 168 0x00079, // Symmetry Island Colored Dots 6
169 0x00065, // Symmetry Island Fading Lines 1 169 0x00065, // Symmetry Island Fading Lines 1
170 0x0006D, // Symmetry Island Fading Lines 2 170 0x0006D, // Symmetry Island Fading Lines 2
171 0x00072, // Symmetry Island Fading Lines 3 171 0x00072, // Symmetry Island Fading Lines 3
172 0x0006F, // Symmetry Island Fading Lines 4 172 0x0006F, // Symmetry Island Fading Lines 4
173 0x00070, // Symmetry Island Fading Lines 5 173 0x00070, // Symmetry Island Fading Lines 5
174 0x00071, // Symmetry Island Fading Lines 6 174 0x00071, // Symmetry Island Fading Lines 6
175 0x00076, // Symmetry Island Fading Lines 7 175 0x00076, // Symmetry Island Fading Lines 7
176 0x00A52, // Symmetry Island Laser Yellow 1 176 0x00A52, // Symmetry Island Laser Yellow 1
177 0x00A57, // Symmetry Island Laser Yellow 2 177 0x00A57, // Symmetry Island Laser Yellow 2
178 0x00A5B, // Symmetry Island Laser Yellow 3 178 0x00A5B, // Symmetry Island Laser Yellow 3
179 0x00A61, // Symmetry Island Laser Blue 1 179 0x00A61, // Symmetry Island Laser Blue 1
180 0x00A64, // Symmetry Island Laser Blue 2 180 0x00A64, // Symmetry Island Laser Blue 2
181 0x00A68, // Symmetry Island Laser Blue 3 181 0x00A68, // Symmetry Island Laser Blue 3
182 0x17CE7, // Desert Discard 182 0x17CE7, // Desert Discard
183 0x0CC7B, // Desert Vault 183 0x0CC7B, // Desert Vault
184 0x01E5A, // Mill Entry Door Left 184 0x01E5A, // Mill Entry Door Left
185 0x01E59, // Mill Entry Door Right 185 0x01E59, // Mill Entry Door Right
186 0x00E0C, // Mill Lower Row 1 186 0x00E0C, // Mill Lower Row 1
187 0x01489, // Mill Lower Row 2 187 0x01489, // Mill Lower Row 2
188 0x0148A, // Mill Lower Row 3 188 0x0148A, // Mill Lower Row 3
189 0x014D9, // Mill Lower Row 4 189 0x014D9, // Mill Lower Row 4
190 0x014E7, // Mill Lower Row 5 190 0x014E7, // Mill Lower Row 5
191 0x014E8, // Mill Lower Row 6 191 0x014E8, // Mill Lower Row 6
192 0x00557, // Mill Upper Row 1 192 0x00557, // Mill Upper Row 1
193 0x005F1, // Mill Upper Row 2 193 0x005F1, // Mill Upper Row 2
194 0x00620, // Mill Upper Row 3 194 0x00620, // Mill Upper Row 3
195 0x009F5, // Mill Upper Row 4 195 0x009F5, // Mill Upper Row 4
196 0x0146C, // Mill Upper Row 5 196 0x0146C, // Mill Upper Row 5
197 0x3C12D, // Mill Upper Row 6 197 0x3C12D, // Mill Upper Row 6
198 0x03686, // Mill Upper Row 7 198 0x03686, // Mill Upper Row 7
199 0x014E9, // Mill Upper Row 8 199 0x014E9, // Mill Upper Row 8
200 0x0367C, // Mill Control Room 1 200 0x0367C, // Mill Control Room 1
201 0x3C125, // Mill Control Room 2 201 0x3C125, // Mill Control Room 2
202 0x03677, // Mill Stairs Control 202 0x03677, // Mill Stairs Control
203 0x17CF0, // Mill Discard 203 0x17CF0, // Mill Discard
204 0x03612, // Quarry Laser 204 0x03612, // Quarry Laser
205 0x021D5, // Boathouse Ramp Activation Shapers 205 0x021D5, // Boathouse Ramp Activation Shapers
206 0x034D4, // Boathouse Ramp Activation Stars 206 0x034D4, // Boathouse Ramp Activation Stars
207 0x021B3, // Boathouse Erasers and Shapers 1 207 0x021B3, // Boathouse Erasers and Shapers 1
208 0x021B4, // Boathouse Erasers and Shapers 2 208 0x021B4, // Boathouse Erasers and Shapers 2
209 0x021B0, // Boathouse Erasers and Shapers 3 209 0x021B0, // Boathouse Erasers and Shapers 3
210 0x021AF, // Boathouse Erasers and Shapers 4 210 0x021AF, // Boathouse Erasers and Shapers 4
211 0x021AE, // Boathouse Erasers and Shapers 5 211 0x021AE, // Boathouse Erasers and Shapers 5
212 0x021B5, // Boathouse Erasers and Stars 1 212 0x021B5, // Boathouse Erasers and Stars 1
213 0x021B6, // Boathouse Erasers and Stars 2 213 0x021B6, // Boathouse Erasers and Stars 2
214 0x021B7, // Boathouse Erasers and Stars 3 214 0x021B7, // Boathouse Erasers and Stars 3
215 0x021BB, // Boathouse Erasers and Stars 4 215 0x021BB, // Boathouse Erasers and Stars 4
216 0x09DB5, // Boathouse Erasers and Stars 5 216 0x09DB5, // Boathouse Erasers and Stars 5
217 0x09DB1, // Boathouse Erasers and Stars 6 217 0x09DB1, // Boathouse Erasers and Stars 6
218 0x3C124, // Boathouse Erasers and Stars 7 218 0x3C124, // Boathouse Erasers and Stars 7
219 0x09DB3, // Boathouse Erasers Shapers and Stars 1 219 0x09DB3, // Boathouse Erasers Shapers and Stars 1
220 0x09DB4, // Boathouse Erasers Shapers and Stars 2 220 0x09DB4, // Boathouse Erasers Shapers and Stars 2
221 0x0A3CB, // Boathouse Erasers Shapers and Stars 3 221 0x0A3CB, // Boathouse Erasers Shapers and Stars 3
222 0x0A3CC, // Boathouse Erasers Shapers and Stars 4 222 0x0A3CC, // Boathouse Erasers Shapers and Stars 4
223 0x0A3D0, // Boathouse Erasers Shapers and Stars 5 223 0x0A3D0, // Boathouse Erasers Shapers and Stars 5
224 0x09E57, // Quarry Entry Gate 1 224 0x09E57, // Quarry Entry Gate 1
225 0x17C09, // Quarry Entry Gate 2 225 0x17C09, // Quarry Entry Gate 2
226 0x0288C, // Treehouse Door 1 226 0x0288C, // Treehouse Door 1
227 0x02886, // Treehouse Door 2 227 0x02886, // Treehouse Door 2
228 0x17D72, // Treehouse Yellow 1 228 0x17D72, // Treehouse Yellow 1
229 0x17D8F, // Treehouse Yellow 2 229 0x17D8F, // Treehouse Yellow 2
230 0x17D74, // Treehouse Yellow 3 230 0x17D74, // Treehouse Yellow 3
231 0x17DAC, // Treehouse Yellow 4 231 0x17DAC, // Treehouse Yellow 4
232 0x17D9E, // Treehouse Yellow 5 232 0x17D9E, // Treehouse Yellow 5
233 0x17DB9, // Treehouse Yellow 6 233 0x17DB9, // Treehouse Yellow 6
234 0x17D9C, // Treehouse Yellow 7 234 0x17D9C, // Treehouse Yellow 7
235 0x17DC2, // Treehouse Yellow 8 235 0x17DC2, // Treehouse Yellow 8
236 0x17DC4, // Treehouse Yellow 9 236 0x17DC4, // Treehouse Yellow 9
237 0x0A182, // Treehouse Door 3 237 0x0A182, // Treehouse Door 3
238 0x17DC8, // Treehouse First Purple 1 238 0x17DC8, // Treehouse First Purple 1
239 0x17DC7, // Treehouse First Purple 2 239 0x17DC7, // Treehouse First Purple 2
240 0x17CE4, // Treehouse First Purple 3 240 0x17CE4, // Treehouse First Purple 3
241 0x17D2D, // Treehouse First Purple 4 241 0x17D2D, // Treehouse First Purple 4
242 0x17D6C, // Treehouse First Purple 5 242 0x17D6C, // Treehouse First Purple 5
243 0x17D9B, // Treehouse Second Purple 1 243 0x17D9B, // Treehouse Second Purple 1
244 0x17D99, // Treehouse Second Purple 2 244 0x17D99, // Treehouse Second Purple 2
245 0x17DAA, // Treehouse Second Purple 3 245 0x17DAA, // Treehouse Second Purple 3
246 0x17D97, // Treehouse Second Purple 4 246 0x17D97, // Treehouse Second Purple 4
247 0x17BDF, // Treehouse Second Purple 5 247 0x17BDF, // Treehouse Second Purple 5
248 0x17D91, // Treehouse Second Purple 6 248 0x17D91, // Treehouse Second Purple 6
249 0x17DC6, // Treehouse Second Purple 7 249 0x17DC6, // Treehouse Second Purple 7
250 0x17DB3, // Treehouse Left Orange 1 250 0x17DB3, // Treehouse Left Orange 1
251 0x17DB5, // Treehouse Left Orange 2 251 0x17DB5, // Treehouse Left Orange 2
252 0x17DB6, // Treehouse Left Orange 3 252 0x17DB6, // Treehouse Left Orange 3
253 0x17DC0, // Treehouse Left Orange 4 253 0x17DC0, // Treehouse Left Orange 4
254 0x17DD7, // Treehouse Left Orange 5 254 0x17DD7, // Treehouse Left Orange 5
255 0x17DD9, // Treehouse Left Orange 6 255 0x17DD9, // Treehouse Left Orange 6
256 0x17DB8, // Treehouse Left Orange 7 256 0x17DB8, // Treehouse Left Orange 7
257 0x17DDC, // Treehouse Left Orange 8 257 0x17DDC, // Treehouse Left Orange 8
258 0x17DDE, // Treehouse Left Orange 10 258 0x17DDE, // Treehouse Left Orange 10
259 0x17DE3, // Treehouse Left Orange 11 259 0x17DE3, // Treehouse Left Orange 11
260 0x17DEC, // Treehouse Left Orange 12 260 0x17DEC, // Treehouse Left Orange 12
261 0x17DAE, // Treehouse Left Orange 13 261 0x17DAE, // Treehouse Left Orange 13
262 0x17DB0, // Treehouse Left Orange 14 262 0x17DB0, // Treehouse Left Orange 14
263 0x17DDB, // Treehouse Left Orange 15 263 0x17DDB, // Treehouse Left Orange 15
264 0x17D88, // Treehouse Right Orange 1 264 0x17D88, // Treehouse Right Orange 1
265 0x17DB4, // Treehouse Right Orange 2 265 0x17DB4, // Treehouse Right Orange 2
266 0x17D8C, // Treehouse Right Orange 3 266 0x17D8C, // Treehouse Right Orange 3
267 0x17DCD, // Treehouse Right Orange 5 267 0x17DCD, // Treehouse Right Orange 5
268 0x17DB2, // Treehouse Right Orange 6 268 0x17DB2, // Treehouse Right Orange 6
269 0x17DCC, // Treehouse Right Orange 7 269 0x17DCC, // Treehouse Right Orange 7
270 0x17DCA, // Treehouse Right Orange 8 270 0x17DCA, // Treehouse Right Orange 8
271 0x17D8E, // Treehouse Right Orange 9 271 0x17D8E, // Treehouse Right Orange 9
272 0x17DB1, // Treehouse Right Orange 11 272 0x17DB1, // Treehouse Right Orange 11
273 0x17DA2, // Treehouse Right Orange 12 273 0x17DA2, // Treehouse Right Orange 12
274 0x17E3C, // Treehouse Green 1 274 0x17E3C, // Treehouse Green 1
275 0x17E4D, // Treehouse Green 2 275 0x17E4D, // Treehouse Green 2
276 0x17E4F, // Treehouse Green 3 276 0x17E4F, // Treehouse Green 3
277 0x17E5B, // Treehouse Green 5 277 0x17E5B, // Treehouse Green 5
278 0x17E5F, // Treehouse Green 6 278 0x17E5F, // Treehouse Green 6
279 0x17E61, // Treehouse Green 7 279 0x17E61, // Treehouse Green 7
280 0x17FA9, // Treehouse Green Bridge Discard 280 0x17FA9, // Treehouse Green Bridge Discard
281 0x17FA0, // Treehouse Laser Discard 281 0x17FA0, // Treehouse Laser Discard
282 0x00139, // Keep Hedges 1 282 0x00139, // Keep Hedges 1
283 0x019DC, // Keep Hedges 2 283 0x019DC, // Keep Hedges 2
284 0x019E7, // Keep Hedges 3 284 0x019E7, // Keep Hedges 3
285 0x01A0F, // Keep Hedges 4 285 0x01A0F, // Keep Hedges 4
286 0x0360E, // Keep Front Laser 286 0x0360E, // Keep Front Laser
287 0x03317, // Keep Back Laser 287 0x03317, // Keep Back Laser
288 0x17D27, // Keep Discard 288 0x17D27, // Keep Discard
289 0x17D28, // Shipwreck Discard 289 0x17D28, // Shipwreck Discard
290 0x00AFB, // Shipwreck Vault 290 0x00AFB, // Shipwreck Vault
291 0x2899C, // Town 25 Dots 1 291 0x2899C, // Town 25 Dots 1
292 0x28A33, // Town 25 Dots 2 292 0x28A33, // Town 25 Dots 2
293 0x28ABF, // Town 25 Dots 3 293 0x28ABF, // Town 25 Dots 3
294 0x28AC0, // Town 25 Dots 4 294 0x28AC0, // Town 25 Dots 4
295 0x28AC1, // Town 25 Dots 5 295 0x28AC1, // Town 25 Dots 5
296 0x28938, // Town Apple Tree 296 0x28938, // Town Apple Tree
297 0x28AC7, // Town Blue 1 297 0x28AC7, // Town Blue 1
298 0x28AC8, // Town Blue 2 298 0x28AC8, // Town Blue 2
299 0x28ACA, // Town Blue 3 299 0x28ACA, // Town Blue 3
300 0x28ACB, // Town Blue 4 300 0x28ACB, // Town Blue 4
301 0x28ACC, // Town Blue 5 301 0x28ACC, // Town Blue 5
302 0x28A0D, // Town Church Stars 302 0x28A0D, // Town Church Stars
303 0x28AD9, // Town Eraser 303 0x28AD9, // Town Eraser
304 0x28998, // Town Green Door 304 0x28998, // Town Green Door
305 0x0A0C8, // Town Orange Crate 305 0x0A0C8, // Town Orange Crate
306 0x17D01, // Town Orange Crate Discard 306 0x17D01, // Town Orange Crate Discard
307 0x03C08, // Town RGB Stars 307 0x03C08, // Town RGB Stars
308 0x03C0C, // Town RGB Stones 308 0x03C0C, // Town RGB Stones
309 0x17C71, // Town Rooftop Discard 309 0x17C71, // Town Rooftop Discard
310 0x17F5F, // Town Windmill Door 310 0x17F5F, // Town Windmill Door
311 0x17F89, // Theater Entrance 311 0x17F89, // Theater Entrance
312 0x17CF7, // Theater Discard 312 0x17CF7, // Theater Discard
313 0x33AB2, // Theater Corona Exit 313 0x33AB2, // Theater Corona Exit
314 0x0A168, // Theater Sun Exit 314 0x0A168, // Theater Sun Exit
315 0x00B10, // Monastery Left Door 315 0x00B10, // Monastery Left Door
316 0x00C92, // Monastery Right Door 316 0x00C92, // Monastery Right Door
317 0x17C2E, // Bunker Entry Door 317 0x17C2E, // Bunker Entry Door
318 0x0056E, // Swamp Entry 318 0x0056E, // Swamp Entry
319 0x00469, // Swamp Tutorial 1 319 0x00469, // Swamp Tutorial 1
320 0x00472, // Swamp Tutorial 2 320 0x00472, // Swamp Tutorial 2
321 0x00262, // Swamp Tutorial 3 321 0x00262, // Swamp Tutorial 3
322 0x00474, // Swamp Tutorial 4 322 0x00474, // Swamp Tutorial 4
323 0x00553, // Swamp Tutorial 5 323 0x00553, // Swamp Tutorial 5
324 0x0056F, // Swamp Tutorial 6 324 0x0056F, // Swamp Tutorial 6
325 0x00390, // Swamp Tutorial 7 325 0x00390, // Swamp Tutorial 7
326 0x010CA, // Swamp Tutorial 8 326 0x010CA, // Swamp Tutorial 8
327 0x00983, // Swamp Tutorial 9 327 0x00983, // Swamp Tutorial 9
328 0x00984, // Swamp Tutorial 10 328 0x00984, // Swamp Tutorial 10
329 0x00986, // Swamp Tutorial 11 329 0x00986, // Swamp Tutorial 11
330 0x00985, // Swamp Tutorial 12 330 0x00985, // Swamp Tutorial 12
331 0x00987, // Swamp Tutorial 13 331 0x00987, // Swamp Tutorial 13
332 0x181A9, // Swamp Tutorial 14 332 0x181A9, // Swamp Tutorial 14
333 0x00982, // Swamp Red 1 333 0x00982, // Swamp Red 1
334 0x0097F, // Swamp Red 2 334 0x0097F, // Swamp Red 2
335 0x0098F, // Swamp Red 3 335 0x0098F, // Swamp Red 3
336 0x00990, // Swamp Red 4 336 0x00990, // Swamp Red 4
337 0x17C0D, // Swamp Red Shortcut 1 337 0x17C0D, // Swamp Red Shortcut 1
338 0x17C0E, // Swamp Red Shortcut 2 338 0x17C0E, // Swamp Red Shortcut 2
339 0x00999, // Swamp Discontinuous 1 339 0x00999, // Swamp Discontinuous 1
340 0x0099D, // Swamp Discontinuous 2 340 0x0099D, // Swamp Discontinuous 2
341 0x009A0, // Swamp Discontinuous 3 341 0x009A0, // Swamp Discontinuous 3
342 0x009A1, // Swamp Discontinuous 4 342 0x009A1, // Swamp Discontinuous 4
343 0x00007, // Swamp Rotation Tutorial 1 343 0x00007, // Swamp Rotation Tutorial 1
344 0x00008, // Swamp Rotation Tutorial 2 344 0x00008, // Swamp Rotation Tutorial 2
345 0x00009, // Swamp Rotation Tutorial 3 345 0x00009, // Swamp Rotation Tutorial 3
346 0x0000A, // Swamp Rotation Tutorial 4 346 0x0000A, // Swamp Rotation Tutorial 4
347 0x009AB, // Swamp Blue Underwater 1 347 0x009AB, // Swamp Blue Underwater 1
348 0x009AD, // Swamp Blue Underwater 2 348 0x009AD, // Swamp Blue Underwater 2
349 0x009AE, // Swamp Blue Underwater 3 349 0x009AE, // Swamp Blue Underwater 3
350 0x009AF, // Swamp Blue Underwater 4 350 0x009AF, // Swamp Blue Underwater 4
351 0x00006, // Swamp Blue Underwater 5 351 0x00006, // Swamp Blue Underwater 5
352 0x003B2, // Swamp Rotation Advanced 1 352 0x003B2, // Swamp Rotation Advanced 1
353 0x00A1E, // Swamp Rotation Advanced 2 353 0x00A1E, // Swamp Rotation Advanced 2
354 0x00C2E, // Swamp Rotation Advanced 3 354 0x00C2E, // Swamp Rotation Advanced 3
355 0x00E3A, // Swamp Rotation Advanced 4 355 0x00E3A, // Swamp Rotation Advanced 4
356 0x009A6, // Swamp Purple Tetris 356 0x009A6, // Swamp Purple Tetris
357 0x00002, // Swamp Teal Underwater 1 357 0x00002, // Swamp Teal Underwater 1
358 0x00004, // Swamp Teal Underwater 2 358 0x00004, // Swamp Teal Underwater 2
359 0x00005, // Swamp Teal Underwater 3 359 0x00005, // Swamp Teal Underwater 3
360 0x013E6, // Swamp Teal Underwater 4 360 0x013E6, // Swamp Teal Underwater 4
361 0x00596, // Swamp Teal Underwater 5 361 0x00596, // Swamp Teal Underwater 5
362 0x00001, // Swamp Red Underwater 1 362 0x00001, // Swamp Red Underwater 1
363 0x014D2, // Swamp Red Underwater 2 363 0x014D2, // Swamp Red Underwater 2
364 0x014D4, // Swamp Red Underwater 3 364 0x014D4, // Swamp Red Underwater 3
365 0x014D1, // Swamp Red Underwater 4 365 0x014D1, // Swamp Red Underwater 4
366 0x17C05, // Swamp Laser Shortcut 1 366 0x17C05, // Swamp Laser Shortcut 1
367 0x17C02, // Swamp Laser Shortcut 2 367 0x17C02, // Swamp Laser Shortcut 2
368 0x17F9B, // Jungle Discard 368 0x17F9B, // Jungle Discard
369 0x09E73, // Mountain 1 Orange 1 369 0x09E73, // Mountain 1 Orange 1
370 0x09E75, // Mountain 1 Orange 2 370 0x09E75, // Mountain 1 Orange 2
371 0x09E78, // Mountain 1 Orange 3 371 0x09E78, // Mountain 1 Orange 3
372 0x09E79, // Mountain 1 Orange 4 372 0x09E79, // Mountain 1 Orange 4
373 0x09E6C, // Mountain 1 Orange 5 373 0x09E6C, // Mountain 1 Orange 5
374 0x09E6F, // Mountain 1 Orange 6 374 0x09E6F, // Mountain 1 Orange 6
375 0x09E6B, // Mountain 1 Orange 7 375 0x09E6B, // Mountain 1 Orange 7
376 0x09EAD, // Mountain 1 Purple 1 376 0x09EAD, // Mountain 1 Purple 1
377 0x09EAF, // Mountain 1 Purple 2 377 0x09EAF, // Mountain 1 Purple 2
378 0x09E7A, // Mountain 1 Green 1 378 0x09E7A, // Mountain 1 Green 1
379 0x09E71, // Mountain 1 Green 2 379 0x09E71, // Mountain 1 Green 2
380 0x09E72, // Mountain 1 Green 3 380 0x09E72, // Mountain 1 Green 3
381 0x09E69, // Mountain 1 Green 4 381 0x09E69, // Mountain 1 Green 4
382 0x09E7B, // Mountain 1 Green 5 382 0x09E7B, // Mountain 1 Green 5
383 0x09FD3, // Mountain 2 Rainbow 1 383 0x09FD3, // Mountain 2 Rainbow 1
384 0x09FD4, // Mountain 2 Rainbow 2 384 0x09FD4, // Mountain 2 Rainbow 2
385 0x09FD6, // Mountain 2 Rainbow 3 385 0x09FD6, // Mountain 2 Rainbow 3
386 0x09FD7, // Mountain 2 Rainbow 4 386 0x09FD7, // Mountain 2 Rainbow 4
387 0x17F93, // Mountain 2 Discard 387 0x17F93, // Mountain 2 Discard
388 0x17FA2, // Mountain 3 Secret Door 388 0x17FA2, // Mountain 3 Secret Door
389 0x17C42, // Mountainside Discard 389 0x17C42, // Mountainside Discard
390 0x002A6, // Mountainside Vault 390 0x002A6, // Mountainside Vault
391 0x0042D, // Mountaintop River 391 0x0042D, // Mountaintop River
392 0x00FF8, // UTM Entrance Door 392 0x00FF8, // UTM Entrance Door
393 0x0A16B, // UTM Green Dots 1 393 0x0A16B, // UTM Green Dots 1
394 0x0A2CE, // UTM Green Dots 2 394 0x0A2CE, // UTM Green Dots 2
395 0x0A2D7, // UTM Green Dots 3 395 0x0A2D7, // UTM Green Dots 3
396 0x0A2DD, // UTM Green Dots 4 396 0x0A2DD, // UTM Green Dots 4
397 0x0A2EA, // UTM Green Dots 5 397 0x0A2EA, // UTM Green Dots 5
398 0x17FB9, // UTM Green Dots 6 398 0x17FB9, // UTM Green Dots 6
399 0x0008F, // UTM Invisible Dots 1 399 0x0008F, // UTM Invisible Dots 1
400 0x0006B, // UTM Invisible Dots 2 400 0x0006B, // UTM Invisible Dots 2
401 0x0008B, // UTM Invisible Dots 3 401 0x0008B, // UTM Invisible Dots 3
402 0x0008C, // UTM Invisible Dots 4 402 0x0008C, // UTM Invisible Dots 4
403 0x0008A, // UTM Invisible Dots 5 403 0x0008A, // UTM Invisible Dots 5
404 0x00089, // UTM Invisible Dots 6 404 0x00089, // UTM Invisible Dots 6
405 0x0006A, // UTM Invisible Dots 7 405 0x0006A, // UTM Invisible Dots 7
406 0x0006C, // UTM Invisible Dots 8 406 0x0006C, // UTM Invisible Dots 8
407 0x00027, // UTM Invisible Dots Symmetry 1 407 0x00027, // UTM Invisible Dots Symmetry 1
408 0x00028, // UTM Invisible Dots Symmetry 2 408 0x00028, // UTM Invisible Dots Symmetry 2
409 0x00029, // UTM Invisible Dots Symmetry 3 409 0x00029, // UTM Invisible Dots Symmetry 3
410 0x021D7, // UTM Mountainside Shortcut 410 0x021D7, // UTM Mountainside Shortcut
411 0x00B71, // UTM Quarry 411 0x00B71, // UTM Quarry
412 0x01A31, // UTM Rainbow 412 0x01A31, // UTM Rainbow
413 0x32962, // UTM Swamp 413 0x32962, // UTM Swamp
414 0x32966, // UTM Treehouse 414 0x32966, // UTM Treehouse
415 0x17CF2, // UTM Waterfall Shortcut 415 0x17CF2, // UTM Waterfall Shortcut
416 0x00A72, // UTM Blue Cave In 416 0x00A72, // UTM Blue Cave In
417 0x009A4, // UTM Blue Discontinuous 417 0x009A4, // UTM Blue Discontinuous
418 0x018A0, // UTM Blue Easy Symmetry 418 0x018A0, // UTM Blue Easy Symmetry
419 0x01A0D, // UTM Blue Hard Symmetry 419 0x01A0D, // UTM Blue Hard Symmetry
420 0x008B8, // UTM Blue Left 1 420 0x008B8, // UTM Blue Left 1
421 0x00973, // UTM Blue Left 2 421 0x00973, // UTM Blue Left 2
422 0x0097B, // UTM Blue Left 3 422 0x0097B, // UTM Blue Left 3
423 0x0097D, // UTM Blue Left 4 423 0x0097D, // UTM Blue Left 4
424 0x0097E, // UTM Blue Left 5 424 0x0097E, // UTM Blue Left 5
425 0x00994, // UTM Blue Right Far 1 425 0x00994, // UTM Blue Right Far 1
426 0x334D5, // UTM Blue Right Far 2 426 0x334D5, // UTM Blue Right Far 2
427 0x00995, // UTM Blue Right Far 3 427 0x00995, // UTM Blue Right Far 3
428 0x00996, // UTM Blue Right Far 4 428 0x00996, // UTM Blue Right Far 4
429 0x00998, // UTM Blue Right Far 5 429 0x00998, // UTM Blue Right Far 5
430 0x00190, // UTM Blue Right Near 1 430 0x00190, // UTM Blue Right Near 1
431 0x00558, // UTM Blue Right Near 2 431 0x00558, // UTM Blue Right Near 2
432 0x00567, // UTM Blue Right Near 3 432 0x00567, // UTM Blue Right Near 3
433 0x006FE, // UTM Blue Right Near 4 433 0x006FE, // UTM Blue Right Near 4
434 0x0A16E, // UTM Challenge Entrance 434 0x0A16E, // UTM Challenge Entrance
435 0x039B4, // Tunnels Theater Catwalk 435 0x039B4, // Tunnels Theater Catwalk
436 0x09E85, // Tunnels Town Shortcut 436 0x09E85, // Tunnels Town Shortcut
437}; 437};
438 438
439std::vector<int> desertPanels = { 439std::vector<int> desertPanels = {
440 0x00698, // Desert Surface 1 440 0x00698, // Desert Surface 1
441 0x0048F, // Desert Surface 2 441 0x0048F, // Desert Surface 2
442 0x09F92, // Desert Surface 3 442 0x09F92, // Desert Surface 3
443 0x0A036, // Desert Surface 4 443 0x0A036, // Desert Surface 4
444 0x09DA6, // Desert Surface 5 444 0x09DA6, // Desert Surface 5
445 0x0A049, // Desert Surface 6 445 0x0A049, // Desert Surface 6
446 0x0A053, // Desert Surface 7 446 0x0A053, // Desert Surface 7
447 0x09F94, // Desert Surface 8 447 0x09F94, // Desert Surface 8
448 0x00422, // Desert Light 1 448 0x00422, // Desert Light 1
449 0x006E3, // Desert Light 2 449 0x006E3, // Desert Light 2
450 0x0A02D, // Desert Light 3 450 0x0A02D, // Desert Light 3
451 0x00C72, // Desert Pond 1 451 0x00C72, // Desert Pond 1
452 0x0129D, // Desert Pond 2 452 0x0129D, // Desert Pond 2
453 0x008BB, // Desert Pond 3 453 0x008BB, // Desert Pond 3
454 0x0078D, // Desert Pond 4 454 0x0078D, // Desert Pond 4
455 0x18313, // Desert Pond 5 455 0x18313, // Desert Pond 5
456 0x04D18, // Desert Flood 1 456 0x04D18, // Desert Flood 1
457 0x01205, // Desert Flood 2 457 0x01205, // Desert Flood 2
458 0x181AB, // Desert Flood 3 458 0x181AB, // Desert Flood 3
459 0x0117A, // Desert Flood 4 459 0x0117A, // Desert Flood 4
460 0x17ECA, // Desert Flood 5 460 0x17ECA, // Desert Flood 5
461// 0x18076, // Desert Flood Exit 461// 0x18076, // Desert Flood Exit
462// 0x0A15C, // Desert Final Left Convex 462// 0x0A15C, // Desert Final Left Convex
463// 0x09FFF, // Desert Final Left Concave 463// 0x09FFF, // Desert Final Left Concave
464// 0x0A15F, // Desert Final Near 464// 0x0A15F, // Desert Final Near
465 0x012D7, // Desert Final Far 465 0x012D7, // Desert Final Far
466}; 466};
467 467
468std::vector<int> shadowsPanels = { 468std::vector<int> shadowsPanels = {
469 0x198B5, // Shadows Tutorial 1 469 0x198B5, // Shadows Tutorial 1
470 0x198BD, // Shadows Tutorial 2 470 0x198BD, // Shadows Tutorial 2
471 0x198BF, // Shadows Tutorial 3 471 0x198BF, // Shadows Tutorial 3
472 0x19771, // Shadows Tutorial 4 472 0x19771, // Shadows Tutorial 4
473 0x0A8DC, // Shadows Tutorial 5 473 0x0A8DC, // Shadows Tutorial 5
474 0x0AC74, // Shadows Tutorial 6 474 0x0AC74, // Shadows Tutorial 6
475 0x0AC7A, // Shadows Tutorial 7 475 0x0AC7A, // Shadows Tutorial 7
476 0x0A8E0, // Shadows Tutorial 8 476 0x0A8E0, // Shadows Tutorial 8
477 0x386FA, // Shadows Avoid 1 477 0x386FA, // Shadows Avoid 1
478 0x1C33F, // Shadows Avoid 2 478 0x1C33F, // Shadows Avoid 2
479 0x196E2, // Shadows Avoid 3 479 0x196E2, // Shadows Avoid 3
480 0x1972A, // Shadows Avoid 4 480 0x1972A, // Shadows Avoid 4
481 0x19809, // Shadows Avoid 5 481 0x19809, // Shadows Avoid 5
482 0x19806, // Shadows Avoid 6 482 0x19806, // Shadows Avoid 6
483 0x196F8, // Shadows Avoid 7 483 0x196F8, // Shadows Avoid 7
484 0x1972F, // Shadows Avoid 8 484 0x1972F, // Shadows Avoid 8
485 0x19797, // Shadows Follow 1 485 0x19797, // Shadows Follow 1
486 0x1979A, // Shadows Follow 2 486 0x1979A, // Shadows Follow 2
487 0x197E0, // Shadows Follow 3 487 0x197E0, // Shadows Follow 3
488 0x197E8, // Shadows Follow 4 488 0x197E8, // Shadows Follow 4
489 0x197E5, // Shadows Follow 5 489 0x197E5, // Shadows Follow 5
490 0x19650, // Shadows Laser 490 0x19650, // Shadows Laser
491}; 491};
492 492
493std::vector<int> monasteryPanels = { 493std::vector<int> monasteryPanels = {
494 0x00B10, // Monastery Left Door 494 0x00B10, // Monastery Left Door
495 0x00C92, // Monastery Right Door 495 0x00C92, // Monastery Right Door
496 0x00290, // Monastery Exterior 1 496 0x00290, // Monastery Exterior 1
497 0x00038, // Monastery Exterior 2 497 0x00038, // Monastery Exterior 2
498 0x00037, // Monastery Exterior 3 498 0x00037, // Monastery Exterior 3
499// 0x09D9B, // Monastery Bonsai 499// 0x09D9B, // Monastery Bonsai
500 0x193A7, // Monastery Interior 1 500 0x193A7, // Monastery Interior 1
501 0x193AA, // Monastery Interior 2 501 0x193AA, // Monastery Interior 2
502 0x193AB, // Monastery Interior 3 502 0x193AB, // Monastery Interior 3
503 0x193A6, // Monastery Interior 4 503 0x193A6, // Monastery Interior 4
504// 0x03713, // Monastery Shortcut 504// 0x03713, // Monastery Shortcut
505 0x17CA4, // Monastery Laser 505 0x17CA4, // Monastery Laser
506}; 506};
507 507
508std::vector<int> bunkerPanels = { 508std::vector<int> bunkerPanels = {
509 0x09F7D, // Bunker Tutorial 1 509 0x09F7D, // Bunker Tutorial 1
510 0x09FDC, // Bunker Tutorial 2 510 0x09FDC, // Bunker Tutorial 2
511 0x09FF7, // Bunker Tutorial 3 511 0x09FF7, // Bunker Tutorial 3
512 0x09F82, // Bunker Tutorial 4 512 0x09F82, // Bunker Tutorial 4
513 0x09FF8, // Bunker Tutorial 5 513 0x09FF8, // Bunker Tutorial 5
514 0x09D9F, // Bunker Advanced 1 514 0x09D9F, // Bunker Advanced 1
515 0x09DA1, // Bunker Advanced 2 515 0x09DA1, // Bunker Advanced 2
516 0x09DA2, // Bunker Advanced 3 516 0x09DA2, // Bunker Advanced 3
517 0x09DAF, // Bunker Advanced 4 517 0x09DAF, // Bunker Advanced 4
518// 0x0A099, // Bunker Glass Door 518// 0x0A099, // Bunker Glass Door
519 0x0A010, // Bunker Glass 1 519 0x0A010, // Bunker Glass 1
520 0x0A01B, // Bunker Glass 2 520 0x0A01B, // Bunker Glass 2
521 0x0A01F, // Bunker Glass 3 521 0x0A01F, // Bunker Glass 3
522 0x17E63, // Bunker Ultraviolet 1 522 0x17E63, // Bunker Ultraviolet 1
523 0x17E67, // Bunker Ultraviolet 2 523 0x17E67, // Bunker Ultraviolet 2
524 0x34BC5, // Bunker Open Ultraviolet 524 0x34BC5, // Bunker Open Ultraviolet
525 0x34BC6, // Bunker Close Ultraviolet 525 0x34BC6, // Bunker Close Ultraviolet
526 0x0A079, // Bunker Elevator 526 0x0A079, // Bunker Elevator
527}; 527};
528 528
529std::vector<int> junglePanels = { 529std::vector<int> junglePanels = {
530 0x002C4, // Jungle Waves 1 530 0x002C4, // Jungle Waves 1
531 0x00767, // Jungle Waves 2 531 0x00767, // Jungle Waves 2
532 0x002C6, // Jungle Waves 3 532 0x002C6, // Jungle Waves 3
533 0x0070E, // Jungle Waves 4 533 0x0070E, // Jungle Waves 4
534 0x0070F, // Jungle Waves 5 534 0x0070F, // Jungle Waves 5
535 0x0087D, // Jungle Waves 6 535 0x0087D, // Jungle Waves 6
536 0x002C7, // Jungle Waves 7 536 0x002C7, // Jungle Waves 7
537// 0x17CAB, // Jungle Pop-up Wall 537// 0x17CAB, // Jungle Pop-up Wall
538 0x0026D, // Jungle Dots 1 538 0x0026D, // Jungle Dots 1
539 0x0026E, // Jungle Dots 2 539 0x0026E, // Jungle Dots 2
540 0x0026F, // Jungle Dots 3 540 0x0026F, // Jungle Dots 3
541 0x00C3F, // Jungle Dots 4 541 0x00C3F, // Jungle Dots 4
542 0x00C41, // Jungle Dots 5 542 0x00C41, // Jungle Dots 5
543 0x014B2, // Jungle Dots 6 543 0x014B2, // Jungle Dots 6
544 0x03616, // Jungle Laser 544 0x03616, // Jungle Laser
545}; 545};
546 546
547std::vector<int> audiologs = { 547std::vector<int> audiologs = {
548 0x3C0F7, // Boat Treehouse Rock 548 0x3C0F7, // Boat Treehouse Rock
549 0x3C0FD, // Boat Broken Boat 549 0x3C0FD, // Boat Broken Boat
550 0x32A00, // Bunker Green Room 550 0x32A00, // Bunker Green Room
551 0x3C0FE, // Desert Broken Wall 551 0x3C0FE, // Desert Broken Wall
552// 0x338B0, // Easter Egg Ending Briefcase (?) 552// 0x338B0, // Easter Egg Ending Briefcase (?)
553// 0x338B7, // Easter Egg Ending Briefcase (?) 553// 0x338B7, // Easter Egg Ending Briefcase (?)
554// 0x338AD, // Easter Egg Ending Briefcase (iOS) 554// 0x338AD, // Easter Egg Ending Briefcase (iOS)
555// 0x338A5, // Easter Egg Ending Wine Table 555// 0x338A5, // Easter Egg Ending Wine Table
556// 0x338AE, // Easter Egg Ending Briefcase 556// 0x338AE, // Easter Egg Ending Briefcase
557// 0x338AF, // Easter Egg Ending Briefcase (?) 557// 0x338AF, // Easter Egg Ending Briefcase (?)
558// 0x338A7, // Easter Egg Ending Record 558// 0x338A7, // Easter Egg Ending Record
559// 0x338A3, // Easter Egg Ending Countertop 559// 0x338A3, // Easter Egg Ending Countertop
560// 0x338A4, // Easter Egg Ending Sunbathing 560// 0x338A4, // Easter Egg Ending Sunbathing
561// 0x3C108, // Easter Egg Ending Pool 561// 0x3C108, // Easter Egg Ending Pool
562// 0x338EF, // Easter Egg Ending Pillow 562// 0x338EF, // Easter Egg Ending Pillow
563// 0x336E5, // Easter Egg Ending Apple 563// 0x336E5, // Easter Egg Ending Apple
564// 0x338A6, // Easter Egg Ending Purple Flowers 564// 0x338A6, // Easter Egg Ending Purple Flowers
565 0x3C100, // Jungle Entrance Right 565 0x3C100, // Jungle Entrance Right
566 0x3C0F4, // Jungle Entrance Left 566 0x3C0F4, // Jungle Entrance Left
567 0x3C102, // Jungle Laser 567 0x3C102, // Jungle Laser
568 0x3C10D, // Jungle Beach 568 0x3C10D, // Jungle Beach
569 0x3C10E, // Keep Corridor 569 0x3C10E, // Keep Corridor
570 0x3C10B, // Keep Guitar Amp 570 0x3C10B, // Keep Guitar Amp
571 0x0074F, // Keep Front Wall 571 0x0074F, // Keep Front Wall
572 0x012C7, // Keep Throne 572 0x012C7, // Keep Throne
573 0x329FF, // Mill Stairs 573 0x329FF, // Mill Stairs
574 0x3C106, // Monastery Left Shutters 574 0x3C106, // Monastery Left Shutters
575 0x33AFF, // Mountain 1 Purple Path Panel 575 0x33AFF, // Mountain 1 Purple Path Panel
576 0x011F9, // Mountain 1 Junk Column 576 0x011F9, // Mountain 1 Junk Column
577 0x00763, // Mountain 1 Blue Panels 577 0x00763, // Mountain 1 Blue Panels
578 0x32A08, // Mountain 2 Blue Path Panel 578 0x32A08, // Mountain 2 Blue Path Panel
579 0x3C101, // Mountain 3 Giant Floor 579 0x3C101, // Mountain 3 Giant Floor
580 0x3C0FF, // Mountain 3 Peekaboo 580 0x3C0FF, // Mountain 3 Peekaboo
581 0x3C103, // Mountainside Cloud Cycle 581 0x3C103, // Mountainside Cloud Cycle
582 0x00A0F, // Mountaintop 582 0x00A0F, // Mountaintop
583 0x339A9, // Outside Tutorial Discard 583 0x339A9, // Outside Tutorial Discard
584 0x015C0, // Outside Tutorial Stones 584 0x015C0, // Outside Tutorial Stones
585 0x33B36, // Peninsula 585 0x33B36, // Peninsula
586 0x3C10C, // Shadows Laser 586 0x3C10C, // Shadows Laser
587 0x32A0E, // Shadows Orange Crate 587 0x32A0E, // Shadows Orange Crate
588 0x329FE, // Shipwreck Bridge 588 0x329FE, // Shipwreck Bridge
589 0x32A07, // Swamp Purple Underwater 589 0x32A07, // Swamp Purple Underwater
590 0x00761, // Swamp Shortcut 590 0x00761, // Swamp Shortcut
591 0x3C109, // Symmetry Island Behind Laser 591 0x3C109, // Symmetry Island Behind Laser
592 0x33B37, // Symmetry Island Fading Lines 592 0x33B37, // Symmetry Island Fading Lines
593 0x3C107, // Town Laser Redirect 593 0x3C107, // Town Laser Redirect
594 0x3C0F3, // Town Bell Tower 594 0x3C0F3, // Town Bell Tower
595 0x015B7, // Town Obelisk 595 0x015B7, // Town Obelisk
596 0x3C10A, // Town Lattice Panel Right 596 0x3C10A, // Town Lattice Panel Right
597 0x32A0A, // Town Lattice Panel Left 597 0x32A0A, // Town Lattice Panel Left
598 0x015C1, // Treehouse Green Bridge 598 0x015C1, // Treehouse Green Bridge
599 0x3C12A, // Treehouse Shipwreck Shore 599 0x3C12A, // Treehouse Shipwreck Shore
600 0x3C104, // Treehouse Docks 600 0x3C104, // Treehouse Docks
601// 0x3C105, // Tunnels Box 601// 0x3C105, // Tunnels Box
602 0x339A8, // Tutorial Patio Roof 602 0x339A8, // Tutorial Patio Roof
603 0x0050A, // Tutorial Gate 603 0x0050A, // Tutorial Gate
604// 0x338BD, // UTM Town Shortcut 604// 0x338BD, // UTM Town Shortcut
605// 0x3C135, // UTM Cave In 605// 0x3C135, // UTM Cave In
606// 0x338C9, // UTM Mountainside Shortcut 606// 0x338C9, // UTM Mountainside Shortcut
607// 0x338D7, // UTM Stairwell 607// 0x338D7, // UTM Stairwell
608// 0x338C1, // UTM Challenge Water 608// 0x338C1, // UTM Challenge Water
609// 0x338CA, // UTM Invisible Dots 609// 0x338CA, // UTM Invisible Dots
610}; 610};
611 611
612std::vector<int> orchard { 612std::vector<int> orchard {
613 0x00143, // Orchard Apple Tree 1 613 0x00143, // Orchard Apple Tree 1
614 0x0003B, // Orchard Apple Tree 2 614 0x0003B, // Orchard Apple Tree 2
615 0x00055, // Orchard Apple Tree 3 615 0x00055, // Orchard Apple Tree 3
616 0x032F7, // Orchard Apple Tree 4 616 0x032F7, // Orchard Apple Tree 4
617 0x032FF, // Orchard Apple Tree 5 617 0x032FF, // Orchard Apple Tree 5
618}; 618};
619 619
620std::vector<int> transparent { 620std::vector<int> transparent {
621 0x009B8, // Symmetry Island Transparent 1 621 0x009B8, // Symmetry Island Transparent 1
622 0x003E8, // Symmetry Island Transparent 2 622 0x003E8, // Symmetry Island Transparent 2
623 0x00A15, // Symmetry Island Transparent 3 623 0x00A15, // Symmetry Island Transparent 3
624 0x00B53, // Symmetry Island Transparent 4 624 0x00B53, // Symmetry Island Transparent 4
625 0x00B8D, // Symmetry Island Transparent 5 625 0x00B8D, // Symmetry Island Transparent 5
626}; 626};
627 627
628// There might be something to do with these, I haven't decided yet. 628// There might be something to do with these, I haven't decided yet.
629std::vector<int> nothingPanels = { 629std::vector<int> nothingPanels = {
630// Doors & Shortcuts & Shortcut doors & Door controls 630// Doors & Shortcuts & Shortcut doors & Door controls
631 0x0C339, // Desert Surface Door 631 0x0C339, // Desert Surface Door
632 0x0A249, // Desert Pond Exit Door 632 0x0A249, // Desert Pond Exit Door
633 0x275ED, // Mill EP Door 633 0x275ED, // Mill EP Door
634 0x17CAC, // Mill Stairs Shortcut Door 634 0x17CAC, // Mill Stairs Shortcut Door
635 0x38663, // Boathouse Shortcut 635 0x38663, // Boathouse Shortcut
636 0x09E49, // Keep Shadows Shortcut 636 0x09E49, // Keep Shadows Shortcut
637 0x0361B, // Keep Tower Shortcut 637 0x0361B, // Keep Tower Shortcut
638 0x334DC, // Shadows Inner Door Control 638 0x334DC, // Shadows Inner Door Control
639 0x334DB, // Shadows Outer Door Control 639 0x334DB, // Shadows Outer Door Control
640 0x2700B, // Treehouse Exterior Door Control 640 0x2700B, // Treehouse Exterior Door Control
641 0x17CBC, // Treehouse Interior Door Control 641 0x17CBC, // Treehouse Interior Door Control
642 0x337FA, // Jungle Shortcut 642 0x337FA, // Jungle Shortcut
643 643
644// Controls (?) 644// Controls (?)
645 0x09FA0, // Desert Surface 3 Control 645 0x09FA0, // Desert Surface 3 Control
646 0x09F86, // Desert Surface 8 Control 646 0x09F86, // Desert Surface 8 Control
647 0x1C2DF, // Desert Flood Control Lower Far Left 647 0x1C2DF, // Desert Flood Control Lower Far Left
648 0x1831E, // Desert Flood Control Lower Far Right 648 0x1831E, // Desert Flood Control Lower Far Right
649 0x1C260, // Desert Flood Control Lower Near Left 649 0x1C260, // Desert Flood Control Lower Near Left
650 0x1831C, // Desert Flood Control Lower Near Right 650 0x1831C, // Desert Flood Control Lower Near Right
651 0x1C2F3, // Desert Flood Control Raise Far Left 651 0x1C2F3, // Desert Flood Control Raise Far Left
652 0x1831D, // Desert Flood Control Raise Far Right 652 0x1831D, // Desert Flood Control Raise Far Right
653 0x1C2B1, // Desert Flood Control Raise Near Left 653 0x1C2B1, // Desert Flood Control Raise Near Left
654 0x1831B, // Desert Flood Control Raise Near Right 654 0x1831B, // Desert Flood Control Raise Near Right
655 0x0A015, // Desert Final Far Control 655 0x0A015, // Desert Final Far Control
656 0x03678, // Mill Lower Ramp Contol 656 0x03678, // Mill Lower Ramp Contol
657 0x03679, // Mill Lower Lift Control 657 0x03679, // Mill Lower Lift Control
658 0x03675, // Mill Upper Lift Control 658 0x03675, // Mill Upper Lift Control
659 0x03676, // Mill Upper Ramp Control 659 0x03676, // Mill Upper Ramp Control
660 0x03852, // Boathouse Ramp Angle Control 660 0x03852, // Boathouse Ramp Angle Control
661 0x03858, // Boathouse Ramp Position Control 661 0x03858, // Boathouse Ramp Position Control
662 0x275FA, // Boathouse Hook Control 662 0x275FA, // Boathouse Hook Control
663 0x037FF, // Treehouse Drawbridge Control 663 0x037FF, // Treehouse Drawbridge Control
664 0x09F98, // Town Laser Redirect Control 664 0x09F98, // Town Laser Redirect Control
665 0x334D8, // Town RGB Light Control 665 0x334D8, // Town RGB Light Control
666 0x17E2B, // Swamp Flood Gate Control 666 0x17E2B, // Swamp Flood Gate Control
667 0x00609, // Swamp Surface Sliding Bridge Control 667 0x00609, // Swamp Surface Sliding Bridge Control
668 0x18488, // Swamp Underwater Sliding Bridge Control 668 0x18488, // Swamp Underwater Sliding Bridge Control
669 0x17C0A, // Swamp Island Control 1 669 0x17C0A, // Swamp Island Control 1
670 0x17E07, // Swamp Island Control 2 670 0x17E07, // Swamp Island Control 2
671 0x181F5, // Swamp Rotating Bridge Control 671 0x181F5, // Swamp Rotating Bridge Control
672 672
673// Vault Boxes 673// Vault Boxes
674 0x03481, // Outside Tutorial Vault Box 674 0x03481, // Outside Tutorial Vault Box
675 0x0339E, // Desert Vault Box 675 0x0339E, // Desert Vault Box
676 0x03535, // Shipwreck Vault Box 676 0x03535, // Shipwreck Vault Box
677 0x03702, // Jungle Vault Box 677 0x03702, // Jungle Vault Box
678 0x03542, // Mountainside Vault Box 678 0x03542, // Mountainside Vault Box
679 0x2FAF6, // Tunnels Vault Box 679 0x2FAF6, // Tunnels Vault Box
680 680
681// Boat Summons 681// Boat Summons
682 0x17CC8, // Glass Factory Summon Boat 682 0x17CC8, // Glass Factory Summon Boat
683 0x17CA6, // Boathouse Summon Boat 683 0x17CA6, // Boathouse Summon Boat
684 0x17C95, // Treehouse Summon Boat 684 0x17C95, // Treehouse Summon Boat
685 0x0A054, // Town Summon Boat 685 0x0A054, // Town Summon Boat
686 0x09DB8, // Swamp Summon Boat 686 0x09DB8, // Swamp Summon Boat
687 0x17CDF, // Jungle Summon Boat 687 0x17CDF, // Jungle Summon Boat
688 688
689// Misc 689// Misc
690 0x03629, // Tutorial Gate Open 690 0x03629, // Tutorial Gate Open
691 0x09FAA, // Desert Lightswitch 691 0x09FAA, // Desert Lightswitch
692 0x0C335, // Tutorial Pillar 692 0x0C335, // Tutorial Pillar
693 0x0C373, // Tutorial Patio floor 693 0x0C373, // Tutorial Patio floor
694 0x1C349, // Symmetry Island Door 2 - Collision fails here, sadly 694 0x1C349, // Symmetry Island Door 2 - Collision fails here, sadly
695 0x033EA, // Keep Yellow Pressure Plates 695 0x033EA, // Keep Yellow Pressure Plates
696 0x0A3A8, // Keep Yellow Reset 696 0x0A3A8, // Keep Yellow Reset
697 0x01BE9, // Keep Purple Pressure Plates 697 0x01BE9, // Keep Purple Pressure Plates
698 0x0A3B9, // Keep Purple Reset 698 0x0A3B9, // Keep Purple Reset
699 0x01CD3, // Keep Green Pressure Plates 699 0x01CD3, // Keep Green Pressure Plates
700 0x0A3BB, // Keep Green Reset 700 0x0A3BB, // Keep Green Reset
701 0x01D3F, // Keep Blue Pressure Plates 701 0x01D3F, // Keep Blue Pressure Plates
702 0x0A3AD, // Keep Blue Reset 702 0x0A3AD, // Keep Blue Reset
703 0x2896A, // Town Bridge 703 0x2896A, // Town Bridge
704 0x28A69, // Town Lattice 704 0x28A69, // Town Lattice
705 0x28A79, // Town Maze 705 0x28A79, // Town Maze
706 0x28B39, // Town Red Hexagonal 706 0x28B39, // Town Red Hexagonal
707 0x034E3, // Town Soundproof Dots 707 0x034E3, // Town Soundproof Dots
708 0x034E4, // Town Soundproof Waves 708 0x034E4, // Town Soundproof Waves
709 0x079DF, // Town Triple 709 0x079DF, // Town Triple
710 0x00815, // Theater Video Input 710 0x00815, // Theater Video Input
711 0x03553, // Theater Tutorial Video 711 0x03553, // Theater Tutorial Video
712 0x03552, // Theater Desert Video 712 0x03552, // Theater Desert Video
713 0x0354E, // Theater Jungle Video 713 0x0354E, // Theater Jungle Video
714 0x03549, // Theater Challenge Video 714 0x03549, // Theater Challenge Video
715 0x0354F, // Theater Shipwreck Video 715 0x0354F, // Theater Shipwreck Video
716 0x03545, // Theater Mountain Video 716 0x03545, // Theater Mountain Video
717 0x18590, // Town Transparent 717 0x18590, // Town Transparent
718 0x28AE3, // Town Wire 718 0x28AE3, // Town Wire
719 719
720 720
721 0x09E39, // Mountain 1 Purple Pathway 721 0x09E39, // Mountain 1 Purple Pathway
722// 0x33AF5, // Mountain 1 Blue 1 722// 0x33AF5, // Mountain 1 Blue 1
723// 0x33AF7, // Mountain 1 Blue 2 723// 0x33AF7, // Mountain 1 Blue 2
724// 0x09F6E, // Mountain 1 Blue 3 724// 0x09F6E, // Mountain 1 Blue 3
725// 0x09FD8, // Mountain 2 Rainbow 5 725// 0x09FD8, // Mountain 2 Rainbow 5
726 0x09E86, // Mountain 2 Blue Pathway 726 0x09E86, // Mountain 2 Blue Pathway
727 0x09ED8, // Mountain 2 Orange Pathway 727 0x09ED8, // Mountain 2 Orange Pathway
728 0x09F8E, // Mountain 3 Near Right Floor 728 0x09F8E, // Mountain 3 Near Right Floor
729 0x09FC1, // Mountain 3 Near Left Floor 729 0x09FC1, // Mountain 3 Near Left Floor
730 0x09F01, // Mountain 3 Far Right Floor 730 0x09F01, // Mountain 3 Far Right Floor
731 0x09EFF, // Mountain 3 Far Left Floor 731 0x09EFF, // Mountain 3 Far Left Floor
732 0x09FDA, // Mountain 3 Giant Floor 732 0x09FDA, // Mountain 3 Giant Floor
733// 0x01983, // Mountain 3 Left Peekaboo 733// 0x01983, // Mountain 3 Left Peekaboo
734// 0x01987, // Mountain 3 Right Peekaboo 734// 0x01987, // Mountain 3 Right Peekaboo
735// 0x3D9A6, // Mountain 3 Left Close Door 735// 0x3D9A6, // Mountain 3 Left Close Door
736// 0x3D9A7, // Mountain 3 Right Close Door 736// 0x3D9A7, // Mountain 3 Right Close Door
737// 0x3D9AA, // Mountain 3 Left Activate Elevator 737// 0x3D9AA, // Mountain 3 Left Activate Elevator
738// 0x3D9A8, // Mountain 3 Right Activate Elevator 738// 0x3D9A8, // Mountain 3 Right Activate Elevator
739// 0x3D9A9, // Mountain 3 Launch Elevator 739// 0x3D9A9, // Mountain 3 Launch Elevator
740// 0x3C113, // Mountain 3 Left Open Door 740// 0x3C113, // Mountain 3 Left Open Door
741// 0x3C114, // Mountain 3 Right Open Door 741// 0x3C114, // Mountain 3 Right Open Door
742 0x09F7F, // Mountaintop Laser Box 742 0x09F7F, // Mountaintop Laser Box
743 0x17C34, // Mountaintop Perspective 743 0x17C34, // Mountaintop Perspective
744// 0x334E1, // UTM Secret Door Control 744// 0x334E1, // UTM Secret Door Control
745// 0x2773D, // Tunnels Desert Shortcut 745// 0x2773D, // Tunnels Desert Shortcut
746// 0x27732, // Tunnels Theater Shortcut 746// 0x27732, // Tunnels Theater Shortcut
747// 0x0A099, // Bunker Glass Door 747// 0x0A099, // Bunker Glass Door
748// 0x15ADD, // Jungle Vault 748// 0x15ADD, // Jungle Vault
749// 0x17CAA, // Jungle Courtyard Gate 749// 0x17CAA, // Jungle Courtyard Gate
750 0x0005C, // Glass Factory Vertical Symmetry 5 750 0x0005C, // Glass Factory Vertical Symmetry 5
751 0x17C31, // Desert Final Transparent 751 0x17C31, // Desert Final Transparent
752 0x19650, // Shadows Laser 752 0x19650, // Shadows Laser
753 0x09EEB, // Mountain 2 Elevator 753 0x09EEB, // Mountain 2 Elevator
754}; 754};
diff --git a/Source/PuzzlerSerializer.h b/Source/PuzzlerSerializer.h index a3d821c..d9b9edd 100644 --- a/Source/PuzzlerSerializer.h +++ b/Source/PuzzlerSerializer.h
@@ -53,9 +53,9 @@ private:
53 std::shared_ptr<Memory> _memory; 53 std::shared_ptr<Memory> _memory;
54 54
55 std::vector<float> _intersectionLocations; 55 std::vector<float> _intersectionLocations;
56 std::vector<int> _intersectionFlags; 56 std::vector<int> _intersectionFlags;
57 std::vector<int> _connectionsA; 57 std::vector<int> _connectionsA;
58 std::vector<int> _connectionsB; 58 std::vector<int> _connectionsB;
59 std::vector<std::tuple<int, int, int>> _endpointLocations; 59 std::vector<std::tuple<int, int, int>> _endpointLocations;
60 60
61 float MIN, MAX, WIDTH_INTERVAL, HEIGHT_INTERVAL, HORIZ_GAP_SIZE, VERTI_GAP_SIZE; 61 float MIN, MAX, WIDTH_INTERVAL, HEIGHT_INTERVAL, HORIZ_GAP_SIZE, VERTI_GAP_SIZE;
diff --git a/Source/Random.cpp b/Source/Random.cpp index d6e86a6..61fd30f 100644 --- a/Source/Random.cpp +++ b/Source/Random.cpp
@@ -4,11 +4,11 @@
4int Random::s_seed = static_cast<int>(time(nullptr)); // Seed from the time in milliseconds 4int Random::s_seed = static_cast<int>(time(nullptr)); // Seed from the time in milliseconds
5 5
6void Random::SetSeed(int seed) { 6void Random::SetSeed(int seed) {
7 s_seed = seed; 7 s_seed = seed;
8} 8}
9 9
10// Returns a random integer in [min, max] 10// Returns a random integer in [min, max]
11int Random::RandInt(int min, int max) { 11int Random::RandInt(int min, int max) {
12 s_seed = (214013 * s_seed + 2531011) % 2147483648; 12 s_seed = (214013 * s_seed + 2531011) % 2147483648;
13 return (s_seed % (max - min + 1)) + min; 13 return (s_seed % (max - min + 1)) + min;
14} 14}
diff --git a/Source/Random.h b/Source/Random.h index 179f0fa..46287a1 100644 --- a/Source/Random.h +++ b/Source/Random.h
@@ -4,9 +4,9 @@
4class Random 4class Random
5{ 5{
6public: 6public:
7 static void SetSeed(int seed); 7 static void SetSeed(int seed);
8 static int RandInt(int min, int max); 8 static int RandInt(int min, int max);
9 9
10private: 10private:
11 static int s_seed; 11 static int s_seed;
12}; 12};
diff --git a/Source/Randomizer.cpp b/Source/Randomizer.cpp index 2545c8f..13f381a 100644 --- a/Source/Randomizer.cpp +++ b/Source/Randomizer.cpp
@@ -102,356 +102,356 @@ Things to do for V2:
102 102
103template <class T> 103template <class T>
104int find(const std::vector<T> &data, T search, size_t startIndex = 0) { 104int find(const std::vector<T> &data, T search, size_t startIndex = 0) {
105 for (size_t i=startIndex ; i<data.size(); i++) { 105 for (size_t i=startIndex ; i<data.size(); i++) {
106 if (data[i] == search) return static_cast<int>(i); 106 if (data[i] == search) return static_cast<int>(i);
107 } 107 }
108 std::cout << "Couldn't find " << search << " in data!" << std::endl; 108 std::cout << "Couldn't find " << search << " in data!" << std::endl;
109 throw std::exception("Couldn't find value in data!"); 109 throw std::exception("Couldn't find value in data!");
110} 110}
111 111
112Randomizer::Randomizer(const std::shared_ptr<Memory>& memory) : _memory(memory) {} 112Randomizer::Randomizer(const std::shared_ptr<Memory>& memory) : _memory(memory) {}
113 113
114void Randomizer::Randomize() { 114void Randomizer::Randomize() {
115 // reveal_exit_hall - Prevent actually ending the game (EEE) 115 // reveal_exit_hall - Prevent actually ending the game (EEE)
116 _memory->AddSigScan({0x45, 0x8B, 0xF7, 0x48, 0x8B, 0x4D}, [&](int index){ 116 _memory->AddSigScan({0x45, 0x8B, 0xF7, 0x48, 0x8B, 0x4D}, [&](int index){
117 _memory->WriteData<byte>({index + 0x15}, {0xEB}); // jz -> jmp 117 _memory->WriteData<byte>({index + 0x15}, {0xEB}); // jz -> jmp
118 }); 118 });
119 119
120 // begin_endgame_1 - Prevent actually ending the game (Wonkavator) 120 // begin_endgame_1 - Prevent actually ending the game (Wonkavator)
121 _memory->AddSigScan({0x83, 0x7C, 0x01, 0xD0, 0x04}, [&](int index){ 121 _memory->AddSigScan({0x83, 0x7C, 0x01, 0xD0, 0x04}, [&](int index){
122 if (GLOBALS == 0x5B28C0) { // Version differences. 122 if (GLOBALS == 0x5B28C0) { // Version differences.
123 index += 0x75; 123 index += 0x75;
124 } else if (GLOBALS == 0x62D0A0) { 124 } else if (GLOBALS == 0x62D0A0) {
125 index += 0x86; 125 index += 0x86;
126 } 126 }
127 _memory->WriteData<byte>({index}, {0xEB}); // jz -> jmp 127 _memory->WriteData<byte>({index}, {0xEB}); // jz -> jmp
128 }); 128 });
129 // Sig scans will be run during challenge randomization. 129 // Sig scans will be run during challenge randomization.
130 130
131 // Seed challenge first for future-proofing 131 // Seed challenge first for future-proofing
132 RandomizeChallenge(); 132 RandomizeChallenge();
133 133
134 // Content swaps -- must happen before squarePanels 134 // Content swaps -- must happen before squarePanels
135 Randomize(upDownPanels, SWAP::LINES | SWAP::COLORS); 135 Randomize(upDownPanels, SWAP::LINES | SWAP::COLORS);
136 Randomize(leftForwardRightPanels, SWAP::LINES | SWAP::COLORS); 136 Randomize(leftForwardRightPanels, SWAP::LINES | SWAP::COLORS);
137 137
138 Randomize(squarePanels, SWAP::LINES | SWAP::COLORS); 138 Randomize(squarePanels, SWAP::LINES | SWAP::COLORS);
139 139
140 // Individual area modifications 140 // Individual area modifications
141 RandomizeTutorial(); 141 RandomizeTutorial();
142 RandomizeDesert(); 142 RandomizeDesert();
143 RandomizeQuarry(); 143 RandomizeQuarry();
144 RandomizeTreehouse(); 144 RandomizeTreehouse();
145 RandomizeKeep(); 145 RandomizeKeep();
146 RandomizeShadows(); 146 RandomizeShadows();
147 RandomizeMonastery(); 147 RandomizeMonastery();
148 RandomizeBunker(); 148 RandomizeBunker();
149 RandomizeJungle(); 149 RandomizeJungle();
150 RandomizeSwamp(); 150 RandomizeSwamp();
151 RandomizeMountain(); 151 RandomizeMountain();
152 RandomizeTown(); 152 RandomizeTown();
153 RandomizeSymmetry(); 153 RandomizeSymmetry();
154 // RandomizeAudioLogs(); 154 // RandomizeAudioLogs();
155} 155}
156 156
157void Randomizer::AdjustSpeed() { 157void Randomizer::AdjustSpeed() {
158 // Desert Surface Final Control 158 // Desert Surface Final Control
159 _memory->WriteEntityData<float>(0x09F95, OPEN_RATE, {0.04f}); // 4x 159 _memory->WriteEntityData<float>(0x09F95, OPEN_RATE, {0.04f}); // 4x
160 // Swamp Sliding Bridge 160 // Swamp Sliding Bridge
161 _memory->WriteEntityData<float>(0x0061A, OPEN_RATE, {0.1f}); // 4x 161 _memory->WriteEntityData<float>(0x0061A, OPEN_RATE, {0.1f}); // 4x
162 // Mountain 2 Elevator 162 // Mountain 2 Elevator
163 _memory->WriteEntityData<float>(0x09EEC, OPEN_RATE, {0.075f}); // 3x 163 _memory->WriteEntityData<float>(0x09EEC, OPEN_RATE, {0.075f}); // 3x
164} 164}
165 165
166void Randomizer::RandomizeLasers() { 166void Randomizer::RandomizeLasers() {
167 Randomize(lasers, SWAP::TARGETS); 167 Randomize(lasers, SWAP::TARGETS);
168 // Read the target of keep front laser, and write it to keep back laser. 168 // Read the target of keep front laser, and write it to keep back laser.
169 std::vector<int> keepFrontLaserTarget = _memory->ReadEntityData<int>(0x0360E, TARGET, 1); 169 std::vector<int> keepFrontLaserTarget = _memory->ReadEntityData<int>(0x0360E, TARGET, 1);
170 _memory->WriteEntityData<int>(0x03317, TARGET, keepFrontLaserTarget); 170 _memory->WriteEntityData<int>(0x03317, TARGET, keepFrontLaserTarget);
171} 171}
172 172
173void Randomizer::PreventSnipes() 173void Randomizer::PreventSnipes()
174{ 174{
175 // Distance-gate swamp snipe 1 to prevent RNG swamp snipe 175 // Distance-gate swamp snipe 1 to prevent RNG swamp snipe
176 _memory->WriteEntityData<float>(0x17C05, MAX_BROADCAST_DISTANCE, {15.0}); 176 _memory->WriteEntityData<float>(0x17C05, MAX_BROADCAST_DISTANCE, {15.0});
177 // Distance-gate shadows laser to prevent sniping through the bars 177 // Distance-gate shadows laser to prevent sniping through the bars
178 _memory->WriteEntityData<float>(0x19650, MAX_BROADCAST_DISTANCE, {2.5}); 178 _memory->WriteEntityData<float>(0x19650, MAX_BROADCAST_DISTANCE, {2.5});
179} 179}
180 180
181// Private methods 181// Private methods
182void Randomizer::RandomizeTutorial() { 182void Randomizer::RandomizeTutorial() {
183 // Disable tutorial cursor speed modifications (not working?) 183 // Disable tutorial cursor speed modifications (not working?)
184 _memory->WriteEntityData<float>(0x00295, CURSOR_SPEED_SCALE, {1.0}); 184 _memory->WriteEntityData<float>(0x00295, CURSOR_SPEED_SCALE, {1.0});
185 _memory->WriteEntityData<float>(0x0C373, CURSOR_SPEED_SCALE, {1.0}); 185 _memory->WriteEntityData<float>(0x0C373, CURSOR_SPEED_SCALE, {1.0});
186 _memory->WriteEntityData<float>(0x00293, CURSOR_SPEED_SCALE, {1.0}); 186 _memory->WriteEntityData<float>(0x00293, CURSOR_SPEED_SCALE, {1.0});
187 _memory->WriteEntityData<float>(0x002C2, CURSOR_SPEED_SCALE, {1.0}); 187 _memory->WriteEntityData<float>(0x002C2, CURSOR_SPEED_SCALE, {1.0});
188} 188}
189 189
190void Randomizer::RandomizeSymmetry() { 190void Randomizer::RandomizeSymmetry() {
191 std::vector<int> randomOrder(transparent.size(), 0); 191 std::vector<int> randomOrder(transparent.size(), 0);
192 std::iota(randomOrder.begin(), randomOrder.end(), 0); 192 std::iota(randomOrder.begin(), randomOrder.end(), 0);
193 RandomizeRange(randomOrder, SWAP::NONE, 1, 5); 193 RandomizeRange(randomOrder, SWAP::NONE, 1, 5);
194 ReassignTargets(transparent, randomOrder); 194 ReassignTargets(transparent, randomOrder);
195} 195}
196 196
197void Randomizer::RandomizeDesert() { 197void Randomizer::RandomizeDesert() {
198 Randomize(desertPanels, SWAP::LINES); 198 Randomize(desertPanels, SWAP::LINES);
199 199
200 // Turn off desert surface 8 200 // Turn off desert surface 8
201 _memory->WriteEntityData<float>(0x09F94, POWER, {0.0, 0.0}); 201 _memory->WriteEntityData<float>(0x09F94, POWER, {0.0, 0.0});
202 // Turn off desert flood final 202 // Turn off desert flood final
203 _memory->WriteEntityData<float>(0x18076, POWER, {0.0, 0.0}); 203 _memory->WriteEntityData<float>(0x18076, POWER, {0.0, 0.0});
204 // Change desert floating target to desert flood final 204 // Change desert floating target to desert flood final
205 _memory->WriteEntityData<int>(0x17ECA, TARGET, {0x18077}); 205 _memory->WriteEntityData<int>(0x17ECA, TARGET, {0x18077});
206} 206}
207 207
208void Randomizer::RandomizeQuarry() { 208void Randomizer::RandomizeQuarry() {
209} 209}
210 210
211void Randomizer::RandomizeTreehouse() { 211void Randomizer::RandomizeTreehouse() {
212 // Ensure that whatever pivot panels we have are flagged as "pivotable" 212 // Ensure that whatever pivot panels we have are flagged as "pivotable"
213 int panelFlags = _memory->ReadEntityData<int>(0x17DD1, STYLE_FLAGS, 1)[0]; 213 int panelFlags = _memory->ReadEntityData<int>(0x17DD1, STYLE_FLAGS, 1)[0];
214 _memory->WriteEntityData<int>(0x17DD1, STYLE_FLAGS, {panelFlags | 0x8000}); 214 _memory->WriteEntityData<int>(0x17DD1, STYLE_FLAGS, {panelFlags | 0x8000});
215 panelFlags = _memory->ReadEntityData<int>(0x17CE3, STYLE_FLAGS, 1)[0]; 215 panelFlags = _memory->ReadEntityData<int>(0x17CE3, STYLE_FLAGS, 1)[0];
216 _memory->WriteEntityData<int>(0x17CE3, STYLE_FLAGS, {panelFlags | 0x8000}); 216 _memory->WriteEntityData<int>(0x17CE3, STYLE_FLAGS, {panelFlags | 0x8000});
217 panelFlags = _memory->ReadEntityData<int>(0x17DB7, STYLE_FLAGS, 1)[0]; 217 panelFlags = _memory->ReadEntityData<int>(0x17DB7, STYLE_FLAGS, 1)[0];
218 _memory->WriteEntityData<int>(0x17DB7, STYLE_FLAGS, {panelFlags | 0x8000}); 218 _memory->WriteEntityData<int>(0x17DB7, STYLE_FLAGS, {panelFlags | 0x8000});
219 panelFlags = _memory->ReadEntityData<int>(0x17E52, STYLE_FLAGS, 1)[0]; 219 panelFlags = _memory->ReadEntityData<int>(0x17E52, STYLE_FLAGS, 1)[0];
220 _memory->WriteEntityData<int>(0x17E52, STYLE_FLAGS, {panelFlags | 0x8000}); 220 _memory->WriteEntityData<int>(0x17E52, STYLE_FLAGS, {panelFlags | 0x8000});
221} 221}
222 222
223void Randomizer::RandomizeKeep() { 223void Randomizer::RandomizeKeep() {
224} 224}
225 225
226void Randomizer::RandomizeShadows() { 226void Randomizer::RandomizeShadows() {
227 // Change the shadows tutorial cable to only activate avoid 227 // Change the shadows tutorial cable to only activate avoid
228 _memory->WriteEntityData<int>(0x319A8, CABLE_TARGET_2, {0}); 228 _memory->WriteEntityData<int>(0x319A8, CABLE_TARGET_2, {0});
229 // Change shadows avoid 8 to power shadows follow 229 // Change shadows avoid 8 to power shadows follow
230 _memory->WriteEntityData<int>(0x1972F, TARGET, {0x1C34C}); 230 _memory->WriteEntityData<int>(0x1972F, TARGET, {0x1C34C});
231 231
232 std::vector<int> randomOrder(shadowsPanels.size(), 0); 232 std::vector<int> randomOrder(shadowsPanels.size(), 0);
233 std::iota(randomOrder.begin(), randomOrder.end(), 0); 233 std::iota(randomOrder.begin(), randomOrder.end(), 0);
234 RandomizeRange(randomOrder, SWAP::NONE, 0, 8); // Tutorial 234 RandomizeRange(randomOrder, SWAP::NONE, 0, 8); // Tutorial
235 RandomizeRange(randomOrder, SWAP::NONE, 8, 16); // Avoid 235 RandomizeRange(randomOrder, SWAP::NONE, 8, 16); // Avoid
236 RandomizeRange(randomOrder, SWAP::NONE, 16, 21); // Follow 236 RandomizeRange(randomOrder, SWAP::NONE, 16, 21); // Follow
237 ReassignTargets(shadowsPanels, randomOrder); 237 ReassignTargets(shadowsPanels, randomOrder);
238 // Turn off original starting panel 238 // Turn off original starting panel
239 _memory->WriteEntityData<float>(shadowsPanels[0], POWER, {0.0f, 0.0f}); 239 _memory->WriteEntityData<float>(shadowsPanels[0], POWER, {0.0f, 0.0f});
240 // Turn on new starting panel 240 // Turn on new starting panel
241 _memory->WriteEntityData<float>(shadowsPanels[randomOrder[0]], POWER, {1.0f, 1.0f}); 241 _memory->WriteEntityData<float>(shadowsPanels[randomOrder[0]], POWER, {1.0f, 1.0f});
242} 242}
243 243
244void Randomizer::RandomizeTown() { 244void Randomizer::RandomizeTown() {
245 // @Hack...? To open the gate at the end 245 // @Hack...? To open the gate at the end
246 std::vector<int> randomOrder(orchard.size() + 1, 0); 246 std::vector<int> randomOrder(orchard.size() + 1, 0);
247 std::iota(randomOrder.begin(), randomOrder.end(), 0); 247 std::iota(randomOrder.begin(), randomOrder.end(), 0);
248 RandomizeRange(randomOrder, SWAP::NONE, 1, 5); 248 RandomizeRange(randomOrder, SWAP::NONE, 1, 5);
249 // Ensure that we open the gate before the final puzzle (by swapping) 249 // Ensure that we open the gate before the final puzzle (by swapping)
250 int panel3Index = find(randomOrder, 3); 250 int panel3Index = find(randomOrder, 3);
251 int panel4Index = find(randomOrder, 4); 251 int panel4Index = find(randomOrder, 4);
252 randomOrder[min(panel3Index, panel4Index)] = 3; 252 randomOrder[min(panel3Index, panel4Index)] = 3;
253 randomOrder[max(panel3Index, panel4Index)] = 4; 253 randomOrder[max(panel3Index, panel4Index)] = 4;
254 ReassignTargets(orchard, randomOrder); 254 ReassignTargets(orchard, randomOrder);
255} 255}
256 256
257void Randomizer::RandomizeMonastery() { 257void Randomizer::RandomizeMonastery() {
258 std::vector<int> randomOrder(monasteryPanels.size(), 0); 258 std::vector<int> randomOrder(monasteryPanels.size(), 0);
259 std::iota(randomOrder.begin(), randomOrder.end(), 0); 259 std::iota(randomOrder.begin(), randomOrder.end(), 0);
260 RandomizeRange(randomOrder, SWAP::NONE, 3, 9); // Outer 2 & 3, Inner 1-4 260 RandomizeRange(randomOrder, SWAP::NONE, 3, 9); // Outer 2 & 3, Inner 1-4
261 ReassignTargets(monasteryPanels, randomOrder); 261 ReassignTargets(monasteryPanels, randomOrder);
262} 262}
263 263
264void Randomizer::RandomizeBunker() { 264void Randomizer::RandomizeBunker() {
265 std::vector<int> randomOrder(bunkerPanels.size(), 0); 265 std::vector<int> randomOrder(bunkerPanels.size(), 0);
266 std::iota(randomOrder.begin(), randomOrder.end(), 0); 266 std::iota(randomOrder.begin(), randomOrder.end(), 0);
267 // Randomize Tutorial 2-Advanced Tutorial 4 + Glass 1 267 // Randomize Tutorial 2-Advanced Tutorial 4 + Glass 1
268 // Tutorial 1 cannot be randomized, since no other panel can start on 268 // Tutorial 1 cannot be randomized, since no other panel can start on
269 // Glass 1 will become door + glass 1, due to the targetting system 269 // Glass 1 will become door + glass 1, due to the targetting system
270 RandomizeRange(randomOrder, SWAP::NONE, 1, 10); 270 RandomizeRange(randomOrder, SWAP::NONE, 1, 10);
271 // Randomize Glass 1-3 into everything after the door/glass 1 271 // Randomize Glass 1-3 into everything after the door/glass 1
272 const size_t glass1Index = find(randomOrder, 9); 272 const size_t glass1Index = find(randomOrder, 9);
273 RandomizeRange(randomOrder, SWAP::NONE, glass1Index + 1, 12); 273 RandomizeRange(randomOrder, SWAP::NONE, glass1Index + 1, 12);
274 ReassignTargets(bunkerPanels, randomOrder); 274 ReassignTargets(bunkerPanels, randomOrder);
275} 275}
276 276
277void Randomizer::RandomizeJungle() { 277void Randomizer::RandomizeJungle() {
278 std::vector<int> randomOrder(junglePanels.size(), 0); 278 std::vector<int> randomOrder(junglePanels.size(), 0);
279 std::iota(randomOrder.begin(), randomOrder.end(), 0); 279 std::iota(randomOrder.begin(), randomOrder.end(), 0);
280 // Waves 1 cannot be randomized, since no other panel can start on 280 // Waves 1 cannot be randomized, since no other panel can start on
281 RandomizeRange(randomOrder, SWAP::NONE, 1, 7); // Waves 2-7 281 RandomizeRange(randomOrder, SWAP::NONE, 1, 7); // Waves 2-7
282 RandomizeRange(randomOrder, SWAP::NONE, 8, 13); // Pitches 1-6 282 RandomizeRange(randomOrder, SWAP::NONE, 8, 13); // Pitches 1-6
283 ReassignTargets(junglePanels, randomOrder); 283 ReassignTargets(junglePanels, randomOrder);
284 284
285 // Fix the wall's target to point back to the cable, and the cable to point to the pitches panel. 285 // Fix the wall's target to point back to the cable, and the cable to point to the pitches panel.
286 // auto wallTarget = _memory->ReadPanelData<int>(junglePanels[7], TARGET, 1); 286 // auto wallTarget = _memory->ReadPanelData<int>(junglePanels[7], TARGET, 1);
287 // _memory->WritePanelData<int>(junglePanels[7], TARGET, {0x3C113}); 287 // _memory->WritePanelData<int>(junglePanels[7], TARGET, {0x3C113});
288 // _memory->WritePanelData<int>(0x3C112, CABLE_TARGET_1, wallTarget); 288 // _memory->WritePanelData<int>(0x3C112, CABLE_TARGET_1, wallTarget);
289} 289}
290 290
291void Randomizer::RandomizeSwamp() { 291void Randomizer::RandomizeSwamp() {
292} 292}
293 293
294void Randomizer::RandomizeMountain() { 294void Randomizer::RandomizeMountain() {
295 // Randomize multipanel 295 // Randomize multipanel
296 Randomize(mountainMultipanel, SWAP::LINES | SWAP::COLORS); 296 Randomize(mountainMultipanel, SWAP::LINES | SWAP::COLORS);
297 297
298 // Randomize final pillars order 298 // Randomize final pillars order
299 std::vector<int> targets = {pillars[0] + 1}; 299 std::vector<int> targets = {pillars[0] + 1};
300 for (const int pillar : pillars) { 300 for (const int pillar : pillars) {
301 int target = _memory->ReadEntityData<int>(pillar, TARGET, 1)[0]; 301 int target = _memory->ReadEntityData<int>(pillar, TARGET, 1)[0];
302 targets.push_back(target); 302 targets.push_back(target);
303 } 303 }
304 targets[5] = pillars[5] + 1; 304 targets[5] = pillars[5] + 1;
305 305
306 std::vector<int> randomOrder(pillars.size(), 0); 306 std::vector<int> randomOrder(pillars.size(), 0);
307 std::iota(randomOrder.begin(), randomOrder.end(), 0); 307 std::iota(randomOrder.begin(), randomOrder.end(), 0);
308 RandomizeRange(randomOrder, SWAP::NONE, 0, 4); // Left Pillars 1-4 308 RandomizeRange(randomOrder, SWAP::NONE, 0, 4); // Left Pillars 1-4
309 RandomizeRange(randomOrder, SWAP::NONE, 5, 9); // Right Pillars 1-4 309 RandomizeRange(randomOrder, SWAP::NONE, 5, 9); // Right Pillars 1-4
310 ReassignTargets(pillars, randomOrder, targets); 310 ReassignTargets(pillars, randomOrder, targets);
311 // Turn off original starting panels 311 // Turn off original starting panels
312 _memory->WriteEntityData<float>(pillars[0], POWER, {0.0f, 0.0f}); 312 _memory->WriteEntityData<float>(pillars[0], POWER, {0.0f, 0.0f});
313 _memory->WriteEntityData<float>(pillars[5], POWER, {0.0f, 0.0f}); 313 _memory->WriteEntityData<float>(pillars[5], POWER, {0.0f, 0.0f});
314 // Turn on new starting panels 314 // Turn on new starting panels
315 _memory->WriteEntityData<float>(pillars[randomOrder[0]], POWER, {1.0f, 1.0f}); 315 _memory->WriteEntityData<float>(pillars[randomOrder[0]], POWER, {1.0f, 1.0f});
316 _memory->WriteEntityData<float>(pillars[randomOrder[5]], POWER, {1.0f, 1.0f}); 316 _memory->WriteEntityData<float>(pillars[randomOrder[5]], POWER, {1.0f, 1.0f});
317} 317}
318 318
319void Randomizer::RandomizeChallenge() { 319void Randomizer::RandomizeChallenge() {
320 ChallengeRandomizer cr(_memory, Random::RandInt(1, 0x7FFFFFFF)); // 0 will trigger an "RNG not initialized" block 320 ChallengeRandomizer cr(_memory, Random::RandInt(1, 0x7FFFFFFF)); // 0 will trigger an "RNG not initialized" block
321 for (int panel : challengePanels) { 321 for (int panel : challengePanels) {
322 _memory->WriteEntityData<int>(panel, POWER_OFF_ON_FAIL, {0}); 322 _memory->WriteEntityData<int>(panel, POWER_OFF_ON_FAIL, {0});
323 } 323 }
324} 324}
325 325
326void Randomizer::RandomizeAudioLogs() { 326void Randomizer::RandomizeAudioLogs() {
327 std::vector<int> randomOrder(audiologs.size(), 0); 327 std::vector<int> randomOrder(audiologs.size(), 0);
328 std::iota(randomOrder.begin(), randomOrder.end(), 0); 328 std::iota(randomOrder.begin(), randomOrder.end(), 0);
329 Randomize(randomOrder, SWAP::NONE); 329 Randomize(randomOrder, SWAP::NONE);
330 ReassignNames(audiologs, randomOrder); 330 ReassignNames(audiologs, randomOrder);
331} 331}
332 332
333void Randomizer::Randomize(std::vector<int>& panels, int flags) { 333void Randomizer::Randomize(std::vector<int>& panels, int flags) {
334 return RandomizeRange(panels, flags, 0, panels.size()); 334 return RandomizeRange(panels, flags, 0, panels.size());
335} 335}
336 336
337// Range is [start, end) 337// Range is [start, end)
338void Randomizer::RandomizeRange(std::vector<int> &panels, int flags, size_t startIndex, size_t endIndex) { 338void Randomizer::RandomizeRange(std::vector<int> &panels, int flags, size_t startIndex, size_t endIndex) {
339 if (panels.size() == 0) return; 339 if (panels.size() == 0) return;
340 if (startIndex >= endIndex) return; 340 if (startIndex >= endIndex) return;
341 if (endIndex >= panels.size()) endIndex = static_cast<int>(panels.size()); 341 if (endIndex >= panels.size()) endIndex = static_cast<int>(panels.size());
342 for (size_t i = endIndex-1; i > startIndex; i--) { 342 for (size_t i = endIndex-1; i > startIndex; i--) {
343 const int target = Random::RandInt(static_cast<int>(startIndex), static_cast<int>(i)); 343 const int target = Random::RandInt(static_cast<int>(startIndex), static_cast<int>(i));
344 if (i != target) { 344 if (i != target) {
345 // std::cout << "Swapping panels " << std::hex << panels[i] << " and " << std::hex << panels[target] << std::endl; 345 // std::cout << "Swapping panels " << std::hex << panels[i] << " and " << std::hex << panels[target] << std::endl;
346 SwapPanels(panels[i], panels[target], flags); 346 SwapPanels(panels[i], panels[target], flags);
347 std::swap(panels[i], panels[target]); // Panel indices in the array 347 std::swap(panels[i], panels[target]); // Panel indices in the array
348 } 348 }
349 } 349 }
350} 350}
351 351
352void Randomizer::SwapPanels(int panel1, int panel2, int flags) { 352void Randomizer::SwapPanels(int panel1, int panel2, int flags) {
353 std::map<int, int> offsets; 353 std::map<int, int> offsets;
354 354
355 if (flags & SWAP::TARGETS) { 355 if (flags & SWAP::TARGETS) {
356 offsets[TARGET] = sizeof(int); 356 offsets[TARGET] = sizeof(int);
357 } 357 }
358 if (flags & SWAP::AUDIO_NAMES) { 358 if (flags & SWAP::AUDIO_NAMES) {
359 offsets[AUDIO_LOG_NAME] = sizeof(void*); 359 offsets[AUDIO_LOG_NAME] = sizeof(void*);
360 } 360 }
361 if (flags & SWAP::COLORS) { 361 if (flags & SWAP::COLORS) {
362 offsets[PATH_COLOR] = 16; 362 offsets[PATH_COLOR] = 16;
363 offsets[REFLECTION_PATH_COLOR] = 16; 363 offsets[REFLECTION_PATH_COLOR] = 16;
364 offsets[DOT_COLOR] = 16; 364 offsets[DOT_COLOR] = 16;
365 offsets[ACTIVE_COLOR] = 16; 365 offsets[ACTIVE_COLOR] = 16;
366 offsets[BACKGROUND_REGION_COLOR] = 12; // Not copying alpha to preserve transparency. 366 offsets[BACKGROUND_REGION_COLOR] = 12; // Not copying alpha to preserve transparency.
367 offsets[SUCCESS_COLOR_A] = 16; 367 offsets[SUCCESS_COLOR_A] = 16;
368 offsets[SUCCESS_COLOR_B] = 16; 368 offsets[SUCCESS_COLOR_B] = 16;
369 offsets[STROBE_COLOR_A] = 16; 369 offsets[STROBE_COLOR_A] = 16;
370 offsets[STROBE_COLOR_B] = 16; 370 offsets[STROBE_COLOR_B] = 16;
371 offsets[ERROR_COLOR] = 16; 371 offsets[ERROR_COLOR] = 16;
372 offsets[PATTERN_POINT_COLOR] = 16; 372 offsets[PATTERN_POINT_COLOR] = 16;
373 offsets[PATTERN_POINT_COLOR_A] = 16; 373 offsets[PATTERN_POINT_COLOR_A] = 16;
374 offsets[PATTERN_POINT_COLOR_B] = 16; 374 offsets[PATTERN_POINT_COLOR_B] = 16;
375 offsets[SYMBOL_A] = 16; 375 offsets[SYMBOL_A] = 16;
376 offsets[SYMBOL_B] = 16; 376 offsets[SYMBOL_B] = 16;
377 offsets[SYMBOL_C] = 16; 377 offsets[SYMBOL_C] = 16;
378 offsets[SYMBOL_D] = 16; 378 offsets[SYMBOL_D] = 16;
379 offsets[SYMBOL_E] = 16; 379 offsets[SYMBOL_E] = 16;
380 offsets[PUSH_SYMBOL_COLORS] = sizeof(int); 380 offsets[PUSH_SYMBOL_COLORS] = sizeof(int);
381 offsets[OUTER_BACKGROUND] = 16; 381 offsets[OUTER_BACKGROUND] = 16;
382 offsets[OUTER_BACKGROUND_MODE] = sizeof(int); 382 offsets[OUTER_BACKGROUND_MODE] = sizeof(int);
383 // These two control the "burn intensity", but I can't swap out burn marks in new ver, so they should probably stay tied to each frame. 383 // These two control the "burn intensity", but I can't swap out burn marks in new ver, so they should probably stay tied to each frame.
384 // offsets[SPECULAR_ADD] = sizeof(float); 384 // offsets[SPECULAR_ADD] = sizeof(float);
385 // offsets[SPECULAR_POWER] = sizeof(int); 385 // offsets[SPECULAR_POWER] = sizeof(int);
386 offsets[NUM_COLORED_REGIONS] = sizeof(int); 386 offsets[NUM_COLORED_REGIONS] = sizeof(int);
387 offsets[COLORED_REGIONS] = sizeof(void*); 387 offsets[COLORED_REGIONS] = sizeof(void*);
388 } 388 }
389 if (flags & SWAP::LINES) { 389 if (flags & SWAP::LINES) {
390 offsets[TRACED_EDGES] = 16; 390 offsets[TRACED_EDGES] = 16;
391 offsets[AUDIO_PREFIX] = sizeof(void*); 391 offsets[AUDIO_PREFIX] = sizeof(void*);
392// offsets[IS_CYLINDER] = sizeof(int); 392// offsets[IS_CYLINDER] = sizeof(int);
393// offsets[CYLINDER_Z0] = sizeof(float); 393// offsets[CYLINDER_Z0] = sizeof(float);
394// offsets[CYLINDER_Z1] = sizeof(float); 394// offsets[CYLINDER_Z1] = sizeof(float);
395// offsets[CYLINDER_RADIUS] = sizeof(float); 395// offsets[CYLINDER_RADIUS] = sizeof(float);
396 offsets[PATH_WIDTH_SCALE] = sizeof(float); 396 offsets[PATH_WIDTH_SCALE] = sizeof(float);
397 offsets[STARTPOINT_SCALE] = sizeof(float); 397 offsets[STARTPOINT_SCALE] = sizeof(float);
398 offsets[NUM_DOTS] = sizeof(int); 398 offsets[NUM_DOTS] = sizeof(int);
399 offsets[NUM_CONNECTIONS] = sizeof(int); 399 offsets[NUM_CONNECTIONS] = sizeof(int);
400 offsets[DOT_POSITIONS] = sizeof(void*); 400 offsets[DOT_POSITIONS] = sizeof(void*);
401 offsets[DOT_FLAGS] = sizeof(void*); 401 offsets[DOT_FLAGS] = sizeof(void*);
402 offsets[DOT_CONNECTION_A] = sizeof(void*); 402 offsets[DOT_CONNECTION_A] = sizeof(void*);
403 offsets[DOT_CONNECTION_B] = sizeof(void*); 403 offsets[DOT_CONNECTION_B] = sizeof(void*);
404 offsets[DECORATIONS] = sizeof(void*); 404 offsets[DECORATIONS] = sizeof(void*);
405 offsets[DECORATION_FLAGS] = sizeof(void*); 405 offsets[DECORATION_FLAGS] = sizeof(void*);
406 offsets[DECORATION_COLORS] = sizeof(void*); 406 offsets[DECORATION_COLORS] = sizeof(void*);
407 offsets[NUM_DECORATIONS] = sizeof(int); 407 offsets[NUM_DECORATIONS] = sizeof(int);
408 offsets[REFLECTION_DATA] = sizeof(void*); 408 offsets[REFLECTION_DATA] = sizeof(void*);
409 offsets[GRID_SIZE_X] = sizeof(int); 409 offsets[GRID_SIZE_X] = sizeof(int);
410 offsets[GRID_SIZE_Y] = sizeof(int); 410 offsets[GRID_SIZE_Y] = sizeof(int);
411 offsets[STYLE_FLAGS] = sizeof(int); 411 offsets[STYLE_FLAGS] = sizeof(int);
412 offsets[SEQUENCE_LEN] = sizeof(int); 412 offsets[SEQUENCE_LEN] = sizeof(int);
413 offsets[SEQUENCE] = sizeof(void*); 413 offsets[SEQUENCE] = sizeof(void*);
414 offsets[DOT_SEQUENCE_LEN] = sizeof(int); 414 offsets[DOT_SEQUENCE_LEN] = sizeof(int);
415 offsets[DOT_SEQUENCE] = sizeof(void*); 415 offsets[DOT_SEQUENCE] = sizeof(void*);
416 offsets[DOT_SEQUENCE_LEN_REFLECTION] = sizeof(int); 416 offsets[DOT_SEQUENCE_LEN_REFLECTION] = sizeof(int);
417 offsets[DOT_SEQUENCE_REFLECTION] = sizeof(void*); 417 offsets[DOT_SEQUENCE_REFLECTION] = sizeof(void*);
418 offsets[PANEL_TARGET] = sizeof(void*); 418 offsets[PANEL_TARGET] = sizeof(void*);
419 offsets[SPECULAR_TEXTURE] = sizeof(void*); 419 offsets[SPECULAR_TEXTURE] = sizeof(void*);
420 } 420 }
421 421
422 for (auto const& [offset, size] : offsets) { 422 for (auto const& [offset, size] : offsets) {
423 std::vector<byte> panel1data = _memory->ReadEntityData<byte>(panel1, offset, size); 423 std::vector<byte> panel1data = _memory->ReadEntityData<byte>(panel1, offset, size);
424 std::vector<byte> panel2data = _memory->ReadEntityData<byte>(panel2, offset, size); 424 std::vector<byte> panel2data = _memory->ReadEntityData<byte>(panel2, offset, size);
425 _memory->WriteEntityData<byte>(panel2, offset, panel1data); 425 _memory->WriteEntityData<byte>(panel2, offset, panel1data);
426 _memory->WriteEntityData<byte>(panel1, offset, panel2data); 426 _memory->WriteEntityData<byte>(panel1, offset, panel2data);
427 } 427 }
428} 428}
429 429
430void Randomizer::ReassignTargets(const std::vector<int>& panels, const std::vector<int>& order, std::vector<int> targets) { 430void Randomizer::ReassignTargets(const std::vector<int>& panels, const std::vector<int>& order, std::vector<int> targets) {
431 if (targets.empty()) { 431 if (targets.empty()) {
432 // This list is offset by 1, so the target of the Nth panel is in position N (aka the N+1th element) 432 // This list is offset by 1, so the target of the Nth panel is in position N (aka the N+1th element)
433 // The first panel may not have a wire to power it, so we use the panel ID itself. 433 // The first panel may not have a wire to power it, so we use the panel ID itself.
434 targets = {panels[0] + 1}; 434 targets = {panels[0] + 1};
435 for (const int panel : panels) { 435 for (const int panel : panels) {
436 int target = _memory->ReadEntityData<int>(panel, TARGET, 1)[0]; 436 int target = _memory->ReadEntityData<int>(panel, TARGET, 1)[0];
437 targets.push_back(target); 437 targets.push_back(target);
438 } 438 }
439 } 439 }
440 440
441 for (size_t i=0; i<order.size() - 1; i++) { 441 for (size_t i=0; i<order.size() - 1; i++) {
442 // Set the target of order[i] to order[i+1], using the "real" target as determined above. 442 // Set the target of order[i] to order[i+1], using the "real" target as determined above.
443 const int panelTarget = targets[order[i+1]]; 443 const int panelTarget = targets[order[i+1]];
444 _memory->WriteEntityData<int>(panels[order[i]], TARGET, {panelTarget}); 444 _memory->WriteEntityData<int>(panels[order[i]], TARGET, {panelTarget});
445 } 445 }
446} 446}
447 447
448void Randomizer::ReassignNames(const std::vector<int>& panels, const std::vector<int>& order) { 448void Randomizer::ReassignNames(const std::vector<int>& panels, const std::vector<int>& order) {
449 std::vector<int64_t> names; 449 std::vector<int64_t> names;
450 for (const int panel : panels) { 450 for (const int panel : panels) {
451 names.push_back(_memory->ReadEntityData<int64_t>(panel, AUDIO_LOG_NAME, 1)[0]); 451 names.push_back(_memory->ReadEntityData<int64_t>(panel, AUDIO_LOG_NAME, 1)[0]);
452 } 452 }
453 453
454 for (int i=0; i<panels.size(); i++) { 454 for (int i=0; i<panels.size(); i++) {
455 _memory->WriteEntityData<int64_t>(panels[i], AUDIO_LOG_NAME, {names[order[i]]}); 455 _memory->WriteEntityData<int64_t>(panels[i], AUDIO_LOG_NAME, {names[order[i]]});
456 } 456 }
457} 457}
diff --git a/Source/Randomizer.h b/Source/Randomizer.h index 87f1f59..673468c 100644 --- a/Source/Randomizer.h +++ b/Source/Randomizer.h
@@ -5,45 +5,45 @@
5class Randomizer { 5class Randomizer {
6public: 6public:
7 Randomizer(const std::shared_ptr<Memory>& memory); 7 Randomizer(const std::shared_ptr<Memory>& memory);
8 void Randomize(); 8 void Randomize();
9 void RandomizeChallenge(); 9 void RandomizeChallenge();
10 10
11 void AdjustSpeed(); 11 void AdjustSpeed();
12 void RandomizeLasers(); 12 void RandomizeLasers();
13 void PreventSnipes(); 13 void PreventSnipes();
14 14
15 enum SWAP { 15 enum SWAP {
16 NONE = 0, 16 NONE = 0,
17 TARGETS = 1, 17 TARGETS = 1,
18 LINES = 2, 18 LINES = 2,
19 AUDIO_NAMES = 4, 19 AUDIO_NAMES = 4,
20 COLORS = 8, 20 COLORS = 8,
21 }; 21 };
22 22
23private: 23private:
24 int _lastRandomizedFrame = 1 << 30; 24 int _lastRandomizedFrame = 1 << 30;
25 void RandomizeTutorial(); 25 void RandomizeTutorial();
26 void RandomizeSymmetry(); 26 void RandomizeSymmetry();
27 void RandomizeDesert(); 27 void RandomizeDesert();
28 void RandomizeQuarry(); 28 void RandomizeQuarry();
29 void RandomizeTreehouse(); 29 void RandomizeTreehouse();
30 void RandomizeKeep(); 30 void RandomizeKeep();
31 void RandomizeShadows(); 31 void RandomizeShadows();
32 void RandomizeTown(); 32 void RandomizeTown();
33 void RandomizeMonastery(); 33 void RandomizeMonastery();
34 void RandomizeBunker(); 34 void RandomizeBunker();
35 void RandomizeJungle(); 35 void RandomizeJungle();
36 void RandomizeSwamp(); 36 void RandomizeSwamp();
37 void RandomizeMountain(); 37 void RandomizeMountain();
38 void RandomizeAudioLogs(); 38 void RandomizeAudioLogs();
39 39
40 void Randomize(std::vector<int>& panels, int flags); 40 void Randomize(std::vector<int>& panels, int flags);
41 void RandomizeRange(std::vector<int> &panels, int flags, size_t startIndex, size_t endIndex); 41 void RandomizeRange(std::vector<int> &panels, int flags, size_t startIndex, size_t endIndex);
42 void SwapPanels(int panel1, int panel2, int flags); 42 void SwapPanels(int panel1, int panel2, int flags);
43 void ReassignTargets(const std::vector<int>& panels, const std::vector<int>& order, std::vector<int> targets = {}); 43 void ReassignTargets(const std::vector<int>& panels, const std::vector<int>& order, std::vector<int> targets = {});
44 void ReassignNames(const std::vector<int>& panels, const std::vector<int>& order); 44 void ReassignNames(const std::vector<int>& panels, const std::vector<int>& order);
45 45
46 std::shared_ptr<Memory> _memory; 46 std::shared_ptr<Memory> _memory;
47 47
48 friend class SwapTests_Shipwreck_Test; 48 friend class SwapTests_Shipwreck_Test;
49}; 49};