diff options
| author | jbzdarkid <jbzdarkid@gmail.com> | 2018-11-06 09:59:34 -0800 | 
|---|---|---|
| committer | jbzdarkid <jbzdarkid@gmail.com> | 2018-11-06 09:59:34 -0800 | 
| commit | faf617739f53c67f663887de34342f92056ba45d (patch) | |
| tree | ea7b4d50b00de8d16fa7f76257972faf143d79e1 /Source/Randomizer.cpp | |
| parent | b54945cf95fa7e4ccc87525d2896901a8f11fe12 (diff) | |
| download | witness-tutorializer-faf617739f53c67f663887de34342f92056ba45d.tar.gz witness-tutorializer-faf617739f53c67f663887de34342f92056ba45d.tar.bz2 witness-tutorializer-faf617739f53c67f663887de34342f92056ba45d.zip | |
Assorted.
Diffstat (limited to 'Source/Randomizer.cpp')
| -rw-r--r-- | Source/Randomizer.cpp | 106 | 
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 | ||
| 32 | short Randomizer::Randomize(int seed) | 29 | bool 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 | |||
| 40 | void 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 | ||
| 67 | void Randomizer::AdjustSpeed() { | 69 | void 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 | ||
| 76 | void Randomizer::RandomizeTutorial() { | 78 | void 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 | ||
| 84 | void Randomizer::RandomizeSymmetry() { | 86 | void 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 | ||
| 98 | void Randomizer::RandomizeQuarry() { | 100 | void Randomizer::RandomizeQuarry() { | 
| @@ -100,14 +102,14 @@ void Randomizer::RandomizeQuarry() { | |||
| 100 | 102 | ||
| 101 | void Randomizer::RandomizeTreehouse() { | 103 | void 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 | ||
| 113 | void Randomizer::RandomizeKeep() { | 115 | void Randomizer::RandomizeKeep() { | 
| @@ -115,11 +117,11 @@ void Randomizer::RandomizeKeep() { | |||
| 115 | 117 | ||
| 116 | void Randomizer::RandomizeShadows() { | 118 | void 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 | ||
| 136 | void Randomizer::RandomizeTown() { | 138 | void Randomizer::RandomizeTown() { | 
| @@ -167,7 +169,7 @@ void Randomizer::RandomizeJungle() { | |||
| 167 | 169 | ||
| 168 | void Randomizer::RandomizeSwamp() { | 170 | void 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 | ||
| 173 | void Randomizer::RandomizeMountain() { | 175 | void 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 | ||
| 203 | void Randomizer::RandomizeChallenge() { | 205 | void 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 | ||
