summary refs log tree commit diff stats
path: root/Source/Randomizer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Randomizer.cpp')
-rw-r--r--Source/Randomizer.cpp106
1 files changed, 54 insertions, 52 deletions
diff --git a/Source/Randomizer.cpp b/Source/Randomizer.cpp index 8833078..3cc2712 100644 --- a/Source/Randomizer.cpp +++ b/Source/Randomizer.cpp
@@ -1,16 +1,13 @@
1/* 1/*
2 * BUGS: 2 * BUGS:
3 * Shipwreck vault is solved reversed? 3 * Shipwreck vault is solved reversed? -> Not reversed, just "half", you can normally solve orange. Seems to need pattern name.
4 * Swamp <-> symmetry has non-invisible background 4 * Tutorial sounds don't always play -> Unsure. Not controlled by pattern name.
5 * Tutorial sounds don't always play
6 * FEATURES: 5 * FEATURES:
7 * Clear "Randomized" button after short delay
8 * Randomize audio logs -- Hard, seem to be unloaded some times? 6 * Randomize audio logs -- Hard, seem to be unloaded some times?
9 * Swap sounds in jungle (along with panels) -- maybe impossible 7 * Swap sounds in jungle (along with panels) -- maybe impossible
10 * Make orange 7 (all of oranges?) hard. Like big = hard. 8 * Make orange 7 (all of oranges?) hard. Like big = hard. (See: HARD_MODE)
11 * Start the game if it isn't running? 9 * Start the game if it isn't running?
12 * Stop swapping colors in desert 10 * Stop swapping colors in desert
13 * Allow users to enter seed after randomly generating seed (aka detect user input in the text box)
14*/ 11*/
15#include "Memory.h" 12#include "Memory.h"
16#include "Randomizer.h" 13#include "Randomizer.h"
@@ -29,15 +26,21 @@ int find(const std::vector<T> &data, T search, size_t startIndex = 0) {
29 exit(-1); 26 exit(-1);
30} 27}
31 28
32short Randomizer::Randomize(int seed) 29bool Randomizer::GameIsRandomized() {
33{ 30 int currentFrame = _core.GetCurrentFrame();
34 short metadata = _core.ReadMetadata(); 31 if (currentFrame >= _lastRandomizedFrame) {
35 if (metadata & 0x1) { 32 // Time went forwards, presumably we're still on the same save
36 // Already randomized -- exit. 33 _lastRandomizedFrame = currentFrame;
37 return metadata; 34 return true;
38 } 35 }
39 _core.WriteMetadata(metadata | 0x1); 36 // Otherwise, time has gone backwards, so assume new game
40 Random::SetSeed(seed); 37 return false;
38}
39
40void Randomizer::Randomize()
41{
42 if (GameIsRandomized()) return; // Nice sanity check, but should be unnecessary (since Main checks anyways)
43 _lastRandomizedFrame = _core.GetCurrentFrame();
41 44
42 // Content swaps -- must happen before squarePanels 45 // Content swaps -- must happen before squarePanels
43 _core.Randomize(upDownPanels, SWAP_LINES); 46 _core.Randomize(upDownPanels, SWAP_LINES);
@@ -61,24 +64,23 @@ short Randomizer::Randomize(int seed)
61 RandomizeMountain(); 64 RandomizeMountain();
62 // RandomizeChallenge(); 65 // RandomizeChallenge();
63 // RandomizeAudioLogs(); 66 // RandomizeAudioLogs();
64 return metadata;
65} 67}
66 68
67void Randomizer::AdjustSpeed() { 69void Randomizer::AdjustSpeed() {
68 // Desert Surface Final Control 70 // Desert Surface Final Control
69 _core._memory.WritePanelData<float>(0x09F95, OPEN_RATE, {0.04f}); // 4x 71 _core._memory->WritePanelData<float>(0x09F95, OPEN_RATE, {0.04f}); // 4x
70 // Swamp Sliding Bridge 72 // Swamp Sliding Bridge
71 _core._memory.WritePanelData<float>(0x0061A, OPEN_RATE, {0.1f}); // 4x 73 _core._memory->WritePanelData<float>(0x0061A, OPEN_RATE, {0.1f}); // 4x
72 // Mountain 2 Elevator 74 // Mountain 2 Elevator
73 _core._memory.WritePanelData<float>(0x09EEC, OPEN_RATE, {0.075f}); // 3x 75 _core._memory->WritePanelData<float>(0x09EEC, OPEN_RATE, {0.075f}); // 3x
74} 76}
75 77
76void Randomizer::RandomizeTutorial() { 78void Randomizer::RandomizeTutorial() {
77 // Disable tutorial cursor speed modifications (not working?) 79 // Disable tutorial cursor speed modifications (not working?)
78 _core._memory.WritePanelData<float>(0x00295, CURSOR_SPEED_SCALE, {1.0}); 80 _core._memory->WritePanelData<float>(0x00295, CURSOR_SPEED_SCALE, {1.0});
79 _core._memory.WritePanelData<float>(0x0C373, CURSOR_SPEED_SCALE, {1.0}); 81 _core._memory->WritePanelData<float>(0x0C373, CURSOR_SPEED_SCALE, {1.0});
80 _core._memory.WritePanelData<float>(0x00293, CURSOR_SPEED_SCALE, {1.0}); 82 _core._memory->WritePanelData<float>(0x00293, CURSOR_SPEED_SCALE, {1.0});
81 _core._memory.WritePanelData<float>(0x002C2, CURSOR_SPEED_SCALE, {1.0}); 83 _core._memory->WritePanelData<float>(0x002C2, CURSOR_SPEED_SCALE, {1.0});
82} 84}
83 85
84void Randomizer::RandomizeSymmetry() { 86void Randomizer::RandomizeSymmetry() {
@@ -88,11 +90,11 @@ void Randomizer::RandomizeDesert() {
88 _core.Randomize(desertPanels, SWAP_LINES); 90 _core.Randomize(desertPanels, SWAP_LINES);
89 91
90 // Turn off desert surface 8 92 // Turn off desert surface 8
91 _core._memory.WritePanelData<float>(0x09F94, POWER, {0.0, 0.0}); 93 _core._memory->WritePanelData<float>(0x09F94, POWER, {0.0, 0.0});
92 // Turn off desert flood final 94 // Turn off desert flood final
93 _core._memory.WritePanelData<float>(0x18076, POWER, {0.0, 0.0}); 95 _core._memory->WritePanelData<float>(0x18076, POWER, {0.0, 0.0});
94 // Change desert floating target to desert flood final 96 // Change desert floating target to desert flood final
95 _core._memory.WritePanelData<int>(0x17ECA, TARGET, {0x18077}); 97 _core._memory->WritePanelData<int>(0x17ECA, TARGET, {0x18077});
96} 98}
97 99
98void Randomizer::RandomizeQuarry() { 100void Randomizer::RandomizeQuarry() {
@@ -100,14 +102,14 @@ void Randomizer::RandomizeQuarry() {
100 102
101void Randomizer::RandomizeTreehouse() { 103void Randomizer::RandomizeTreehouse() {
102 // Ensure that whatever pivot panels we have are flagged as "pivotable" 104 // Ensure that whatever pivot panels we have are flagged as "pivotable"
103 int panelFlags = _core._memory.ReadPanelData<int>(0x17DD1, STYLE_FLAGS, 1)[0]; 105 int panelFlags = _core._memory->ReadPanelData<int>(0x17DD1, STYLE_FLAGS, 1)[0];
104 _core._memory.WritePanelData<int>(0x17DD1, STYLE_FLAGS, {panelFlags | 0x8000}); 106 _core._memory->WritePanelData<int>(0x17DD1, STYLE_FLAGS, {panelFlags | 0x8000});
105 panelFlags = _core._memory.ReadPanelData<int>(0x17CE3, STYLE_FLAGS, 1)[0]; 107 panelFlags = _core._memory->ReadPanelData<int>(0x17CE3, STYLE_FLAGS, 1)[0];
106 _core._memory.WritePanelData<int>(0x17CE3, STYLE_FLAGS, {panelFlags | 0x8000}); 108 _core._memory->WritePanelData<int>(0x17CE3, STYLE_FLAGS, {panelFlags | 0x8000});
107 panelFlags = _core._memory.ReadPanelData<int>(0x17DB7, STYLE_FLAGS, 1)[0]; 109 panelFlags = _core._memory->ReadPanelData<int>(0x17DB7, STYLE_FLAGS, 1)[0];
108 _core._memory.WritePanelData<int>(0x17DB7, STYLE_FLAGS, {panelFlags | 0x8000}); 110 _core._memory->WritePanelData<int>(0x17DB7, STYLE_FLAGS, {panelFlags | 0x8000});
109 panelFlags = _core._memory.ReadPanelData<int>(0x17E52, STYLE_FLAGS, 1)[0]; 111 panelFlags = _core._memory->ReadPanelData<int>(0x17E52, STYLE_FLAGS, 1)[0];
110 _core._memory.WritePanelData<int>(0x17E52, STYLE_FLAGS, {panelFlags | 0x8000}); 112 _core._memory->WritePanelData<int>(0x17E52, STYLE_FLAGS, {panelFlags | 0x8000});
111} 113}
112 114
113void Randomizer::RandomizeKeep() { 115void Randomizer::RandomizeKeep() {
@@ -115,11 +117,11 @@ void Randomizer::RandomizeKeep() {
115 117
116void Randomizer::RandomizeShadows() { 118void Randomizer::RandomizeShadows() {
117 // Distance-gate shadows laser to prevent sniping through the bars 119 // Distance-gate shadows laser to prevent sniping through the bars
118 _core._memory.WritePanelData<float>(0x19650, MAX_BROADCAST_DISTANCE, {2.5}); 120 _core._memory->WritePanelData<float>(0x19650, MAX_BROADCAST_DISTANCE, {2.5});
119 // Change the shadows tutorial cable to only activate avoid 121 // Change the shadows tutorial cable to only activate avoid
120 _core._memory.WritePanelData<int>(0x319A8, CABLE_TARGET_2, {0}); 122 _core._memory->WritePanelData<int>(0x319A8, CABLE_TARGET_2, {0});
121 // Change shadows avoid 8 to power shadows follow 123 // Change shadows avoid 8 to power shadows follow
122 _core._memory.WritePanelData<int>(0x1972F, TARGET, {0x1C34C}); 124 _core._memory->WritePanelData<int>(0x1972F, TARGET, {0x1C34C});
123 125
124 std::vector<int> randomOrder(shadowsPanels.size(), 0); 126 std::vector<int> randomOrder(shadowsPanels.size(), 0);
125 std::iota(randomOrder.begin(), randomOrder.end(), 0); 127 std::iota(randomOrder.begin(), randomOrder.end(), 0);
@@ -128,9 +130,9 @@ void Randomizer::RandomizeShadows() {
128 _core.RandomizeRange(randomOrder, SWAP_NONE, 16, 21); // Follow 130 _core.RandomizeRange(randomOrder, SWAP_NONE, 16, 21); // Follow
129 _core.ReassignTargets(shadowsPanels, randomOrder); 131 _core.ReassignTargets(shadowsPanels, randomOrder);
130 // Turn off original starting panel 132 // Turn off original starting panel
131 _core._memory.WritePanelData<float>(shadowsPanels[0], POWER, {0.0f, 0.0f}); 133 _core._memory->WritePanelData<float>(shadowsPanels[0], POWER, {0.0f, 0.0f});
132 // Turn on new starting panel 134 // Turn on new starting panel
133 _core._memory.WritePanelData<float>(shadowsPanels[randomOrder[0]], POWER, {1.0f, 1.0f}); 135 _core._memory->WritePanelData<float>(shadowsPanels[randomOrder[0]], POWER, {1.0f, 1.0f});
134} 136}
135 137
136void Randomizer::RandomizeTown() { 138void Randomizer::RandomizeTown() {
@@ -167,7 +169,7 @@ void Randomizer::RandomizeJungle() {
167 169
168void Randomizer::RandomizeSwamp() { 170void Randomizer::RandomizeSwamp() {
169 // Distance-gate swamp snipe 1 to prevent RNG swamp snipe 171 // Distance-gate swamp snipe 1 to prevent RNG swamp snipe
170 _core._memory.WritePanelData<float>(0x17C05, MAX_BROADCAST_DISTANCE, {15.0}); 172 _core._memory->WritePanelData<float>(0x17C05, MAX_BROADCAST_DISTANCE, {15.0});
171} 173}
172 174
173void Randomizer::RandomizeMountain() { 175void Randomizer::RandomizeMountain() {
@@ -178,7 +180,7 @@ void Randomizer::RandomizeMountain() {
178 // Randomize final pillars order 180 // Randomize final pillars order
179 std::vector<int> targets = {pillars[0] + 1}; 181 std::vector<int> targets = {pillars[0] + 1};
180 for (const int pillar : pillars) { 182 for (const int pillar : pillars) {
181 int target = _core._memory.ReadPanelData<int>(pillar, TARGET, 1)[0]; 183 int target = _core._memory->ReadPanelData<int>(pillar, TARGET, 1)[0];
182 targets.push_back(target); 184 targets.push_back(target);
183 } 185 }
184 targets[5] = pillars[5] + 1; 186 targets[5] = pillars[5] + 1;
@@ -189,27 +191,27 @@ void Randomizer::RandomizeMountain() {
189 _core.RandomizeRange(randomOrder, SWAP_NONE, 5, 9); // Right Pillars 1-4 191 _core.RandomizeRange(randomOrder, SWAP_NONE, 5, 9); // Right Pillars 1-4
190 _core.ReassignTargets(pillars, randomOrder, targets); 192 _core.ReassignTargets(pillars, randomOrder, targets);
191 // Turn off original starting panels 193 // Turn off original starting panels
192 _core._memory.WritePanelData<float>(pillars[0], POWER, {0.0f, 0.0f}); 194 _core._memory->WritePanelData<float>(pillars[0], POWER, {0.0f, 0.0f});
193 _core._memory.WritePanelData<float>(pillars[5], POWER, {0.0f, 0.0f}); 195 _core._memory->WritePanelData<float>(pillars[5], POWER, {0.0f, 0.0f});
194 // Turn on new starting panels 196 // Turn on new starting panels
195 _core._memory.WritePanelData<float>(pillars[randomOrder[0]], POWER, {1.0f, 1.0f}); 197 _core._memory->WritePanelData<float>(pillars[randomOrder[0]], POWER, {1.0f, 1.0f});
196 _core._memory.WritePanelData<float>(pillars[randomOrder[5]], POWER, {1.0f, 1.0f}); 198 _core._memory->WritePanelData<float>(pillars[randomOrder[5]], POWER, {1.0f, 1.0f});
197 199
198 // Read the target of keep front laser, and write it to keep back laser. 200 // Read the target of keep front laser, and write it to keep back laser.
199 std::vector<int> keepFrontLaserTarget = _core._memory.ReadPanelData<int>(0x0360E, TARGET, 1); 201 std::vector<int> keepFrontLaserTarget = _core._memory->ReadPanelData<int>(0x0360E, TARGET, 1);
200 _core._memory.WritePanelData<int>(0x03317, TARGET, keepFrontLaserTarget); 202 _core._memory->WritePanelData<int>(0x03317, TARGET, keepFrontLaserTarget);
201} 203}
202 204
203void Randomizer::RandomizeChallenge() { 205void Randomizer::RandomizeChallenge() {
204 std::vector<int> randomOrder(challengePanels.size(), 0); 206 std::vector<int> randomOrder(challengePanels.size(), 0);
205 std::iota(randomOrder.begin(), randomOrder.end(), 0); 207 std::iota(randomOrder.begin(), randomOrder.end(), 0);
206 _core.RandomizeRange(randomOrder, SWAP_NONE, 1, 9); // Easy maze - Triple 2 208 _core.RandomizeRange(randomOrder, SWAP_NONE, 1, 9); // Easy maze - Triple 2
207 std::vector<int> triple1Target = _core._memory.ReadPanelData<int>(0x00C80, TARGET, 1); 209 std::vector<int> triple1Target = _core._memory->ReadPanelData<int>(0x00C80, TARGET, 1);
208 _core._memory.WritePanelData<int>(0x00CA1, TARGET, triple1Target); 210 _core._memory->WritePanelData<int>(0x00CA1, TARGET, triple1Target);
209 _core._memory.WritePanelData<int>(0x00CB9, TARGET, triple1Target); 211 _core._memory->WritePanelData<int>(0x00CB9, TARGET, triple1Target);
210 std::vector<int> triple2Target = _core._memory.ReadPanelData<int>(0x00C22, TARGET, 1); 212 std::vector<int> triple2Target = _core._memory->ReadPanelData<int>(0x00C22, TARGET, 1);
211 _core._memory.WritePanelData<int>(0x00C59, TARGET, triple2Target); 213 _core._memory->WritePanelData<int>(0x00C59, TARGET, triple2Target);
212 _core._memory.WritePanelData<int>(0x00C68, TARGET, triple2Target); 214 _core._memory->WritePanelData<int>(0x00C68, TARGET, triple2Target);
213 _core.ReassignTargets(challengePanels, randomOrder); 215 _core.ReassignTargets(challengePanels, randomOrder);
214} 216}
215 217