From 38475fd9c286667a235b6f609ccf2689949202fd Mon Sep 17 00:00:00 2001 From: jbzdarkid Date: Sun, 28 Oct 2018 16:55:57 -0700 Subject: Add (not working) challenge randomization, hopefully fix treehouse, fix mountain elevator? --- Source/Panels.h | 37 +++++-- Source/Randomizer.cpp | 58 ++++++---- Source/Randomizer.h | 4 +- Source/RandomizerCore.cpp | 9 -- .../RandomizerCore.cpp | 119 +++++++++++++++++++++ 5 files changed, 189 insertions(+), 38 deletions(-) create mode 100644 enc_temp_folder/39556c61ea71e3139a19e47cd4dbe2/RandomizerCore.cpp diff --git a/Source/Panels.h b/Source/Panels.h index b3a7791..2187d57 100644 --- a/Source/Panels.h +++ b/Source/Panels.h @@ -34,10 +34,8 @@ std::vector leftRightPanels = { // These panels are very tall (aka not square) and can't take symmetry panels on them. std::vector tallUpDownPanels = { - 0x335AB, // UTM In Elevator Control - 0x3369D, // UTM Lower Elevator Control - 0x335AC, // UTM Upper Elevator Control 0x09EEB, // Mountain 2 Elevator + 0x17CC4, // Mill Elevator Control }; // Note: Some of these (non-controls) are duplicated elsewhere @@ -57,6 +55,9 @@ std::vector upDownPanels = { 0x0A3B5, // Tutorial Back Left 0x17CC4, // Mill Elevator Control +// 0x335AB, // UTM In Elevator Control +// 0x3369D, // UTM Lower Elevator Control +// 0x335AC, // UTM Upper Elevator Control }; // Note: Some of these (non-controls) are duplicated elsewhere @@ -81,9 +82,33 @@ std::vector pillars = { 0x09E56, // Mountain 3 Right Pillar 2 0x09E5A, // Mountain 3 Right Pillar 3 0x33961, // Mountain 3 Right Pillar 4 - 0x09DD5, // UTM Challenge Pillar -// 0x1C31A, // Challenge Left Pillar -// 0x1C319, // Challenge Right Pillar +// 0x09DD5, // UTM Challenge Pillar +}; + +std::vector challengePanels = { + 0x0A332, // Challenge Record Start + 0x0088E, // Challenge Easy Maze + 0x00BAF, // Challenge Hard Maze + 0x00BF3, // Challenge Stones Maze + 0x00C09, // Challenge Pedestal + 0x0051F, // Challenge Column Bottom Left + 0x00524, // Challenge Column Top Right + 0x00CDB, // Challenge Column Top Left + 0x00CD4, // Challenge Column Far Panel + 0x00C80, // Challenge Triple 1 Left +// 0x00CA1, // Challenge Triple 1 Center +// 0x00CB9, // Challenge Triple 1 Right + 0x00C22, // Challenge Triple 2 Left +// 0x00C59, // Challenge Triple 2 Center +// 0x00C68, // Challenge Triple 2 Right +// 0x04CB3, // Challenge Left Timer +// 0x04CB5, // Challenge Middle Timer +// 0x04CB6, // Challenge Right Timer + 0x034EC, // Challenge Triangle + 0x034F4, // Challenge Triangle + 0x1C31A, // Challenge Left Pillar + 0x1C319, // Challenge Right Pillar +// 0x0356B, // Challenge Vault Box }; std::vector mountainMultipanel = { diff --git a/Source/Randomizer.cpp b/Source/Randomizer.cpp index 8c4297d..6729ae7 100644 --- a/Source/Randomizer.cpp +++ b/Source/Randomizer.cpp @@ -1,18 +1,15 @@ /* - * TODO: Split out main() logic into another file, and move into separate functions for easier testing. Then write tests. * BUGS: - * Shipwreck vault fails, possibly because of dot_reflection? Sometimes? - * Some panels are impossible casually: (idc, I think) - ** Town Stars, Invisible dots + * Shipwreck vault is solved reversed? + * Extra_back_distance to make pillar swaps work + * Verify UTM perspective? * FEATURES: - * SWAP_TARGETS should still require the full panel sequence (and have ways to prevent softlocks?) - ** Do: Challenge + * Challenge randomization * Randomize audio logs * Swap sounds in jungle (along with panels) -- maybe impossible * Make orange 7 (all of oranges?) hard. Like big = hard. * Start the game if it isn't running? - * UI for the randomizer :( - * Increase odds of mountain oranges garbage on other panels? + * Increase odds of mountain oranges garbage on other panels? [setting] */ #include "Memory.h" #include "Randomizer.h" @@ -34,11 +31,11 @@ int find(const std::vector &data, T search, size_t startIndex = 0) { void Randomizer::Randomize() { // Content swaps -- must happen before squarePanels - _core.Randomize(tallUpDownPanels, SWAP_LINES|SWAP_LINES); - _core.Randomize(upDownPanels, SWAP_LINES|SWAP_LINES); - _core.Randomize(leftForwardRightPanels, SWAP_LINES|SWAP_LINES); + _core.Randomize(tallUpDownPanels, SWAP_LINES); + _core.Randomize(upDownPanels, SWAP_LINES); + _core.Randomize(leftForwardRightPanels, SWAP_LINES); - _core.Randomize(squarePanels, SWAP_LINES|SWAP_LINES); + _core.Randomize(squarePanels, SWAP_LINES); // Individual area modifications RandomizeTutorial(); @@ -54,6 +51,7 @@ void Randomizer::Randomize() RandomizeJungle(); RandomizeSwamp(); RandomizeMountain(); + // RandomizeChallenge(); } void Randomizer::RandomizeTutorial() { @@ -68,7 +66,7 @@ void Randomizer::RandomizeSymmetry() { } void Randomizer::RandomizeDesert() { - _core.Randomize(desertPanels, SWAP_LINES|SWAP_LINES); + _core.Randomize(desertPanels, SWAP_LINES); // Turn off desert surface 8 _core.WritePanelData(0x09F94, POWER, {0.0, 0.0}); @@ -83,10 +81,14 @@ void Randomizer::RandomizeQuarry() { void Randomizer::RandomizeTreehouse() { // Ensure that whatever pivot panels we have are flagged as "pivotable" - _core.WritePanelData(0x17DD1, STYLE_FLAGS, {0x8000}); - _core.WritePanelData(0x17CE3, STYLE_FLAGS, {0x8000}); - _core.WritePanelData(0x17DB7, STYLE_FLAGS, {0x8000}); - _core.WritePanelData(0x17E52, STYLE_FLAGS, {0x8000}); + int panelFlags = _core.ReadPanelData(0x17DD1, STYLE_FLAGS, 1)[0]; + _core.WritePanelData(0x17DD1, STYLE_FLAGS, {panelFlags | 0x8000}); + panelFlags = _core.ReadPanelData(0x17CE3, STYLE_FLAGS, 1)[0]; + _core.WritePanelData(0x17CE3, STYLE_FLAGS, {panelFlags | 0x8000}); + panelFlags = _core.ReadPanelData(0x17DB7, STYLE_FLAGS, 1)[0]; + _core.WritePanelData(0x17DB7, STYLE_FLAGS, {panelFlags | 0x8000}); + panelFlags = _core.ReadPanelData(0x17E52, STYLE_FLAGS, 1)[0]; + _core.WritePanelData(0x17E52, STYLE_FLAGS, {panelFlags | 0x8000}); } void Randomizer::RandomizeKeep() { @@ -138,11 +140,9 @@ void Randomizer::RandomizeBunker() { void Randomizer::RandomizeJungle() { std::vector randomOrder(junglePanels.size(), 0); std::iota(randomOrder.begin(), randomOrder.end(), 0); - // Randomize Waves 2-7 // Waves 1 cannot be randomized, since no other panel can start on - _core.RandomizeRange(randomOrder, SWAP_NONE, 1, 7); - // Randomize Pitches 1-6 onto themselves - _core.RandomizeRange(randomOrder, SWAP_NONE, 8, 13); + _core.RandomizeRange(randomOrder, SWAP_NONE, 1, 7); // Waves 2-7 + _core.RandomizeRange(randomOrder, SWAP_NONE, 8, 13); // Pitches 1-6 _core.ReassignTargets(junglePanels, randomOrder); } @@ -153,9 +153,23 @@ void Randomizer::RandomizeSwamp() { void Randomizer::RandomizeMountain() { _core.Randomize(lasers, SWAP_TARGETS); - _core.Randomize(pillars, SWAP_LINES|SWAP_LINES); + _core.Randomize(pillars, SWAP_LINES); + _core.Randomize(mountainMultipanel, SWAP_LINES); // Read the target of keep front laser, and write it to keep back laser. std::vector keepFrontLaserTarget = _core.ReadPanelData(0x0360E, TARGET, 1); _core.WritePanelData(0x03317, TARGET, keepFrontLaserTarget); +} + +void Randomizer::RandomizeChallenge() { + std::vector randomOrder(challengePanels.size(), 0); + std::iota(randomOrder.begin(), randomOrder.end(), 0); + _core.RandomizeRange(randomOrder, SWAP_NONE, 1, 11); // Easy maze - Triple 2 + std::vector triple1Target = _core.ReadPanelData(0x00C80, TARGET, 1); + _core.WritePanelData(0x00CA1, TARGET, triple1Target); + _core.WritePanelData(0x00CB9, TARGET, triple1Target); + std::vector triple2Target = _core.ReadPanelData(0x00C22, TARGET, 1); + _core.WritePanelData(0x00C59, TARGET, triple2Target); + _core.WritePanelData(0x00C68, TARGET, triple2Target); + _core.ReassignTargets(challengePanels, randomOrder); } \ No newline at end of file diff --git a/Source/Randomizer.h b/Source/Randomizer.h index 861f5a2..82ea924 100644 --- a/Source/Randomizer.h +++ b/Source/Randomizer.h @@ -6,7 +6,6 @@ public: void Randomize(); private: - RandomizerCore _core; void RandomizeTutorial(); void RandomizeSymmetry(); void RandomizeDesert(); @@ -20,4 +19,7 @@ private: void RandomizeJungle(); void RandomizeSwamp(); void RandomizeMountain(); + void RandomizeChallenge(); + + RandomizerCore _core; }; diff --git a/Source/RandomizerCore.cpp b/Source/RandomizerCore.cpp index ef0e6e6..d8d8014 100644 --- a/Source/RandomizerCore.cpp +++ b/Source/RandomizerCore.cpp @@ -105,15 +105,6 @@ void RandomizerCore::ReassignTargets(const std::vector& panels, const std:: for (size_t i=0; i(panels[order[i]], TARGET, {panelTarget}); } } diff --git a/enc_temp_folder/39556c61ea71e3139a19e47cd4dbe2/RandomizerCore.cpp b/enc_temp_folder/39556c61ea71e3139a19e47cd4dbe2/RandomizerCore.cpp new file mode 100644 index 0000000..ef0e6e6 --- /dev/null +++ b/enc_temp_folder/39556c61ea71e3139a19e47cd4dbe2/RandomizerCore.cpp @@ -0,0 +1,119 @@ +#include "RandomizerCore.h" +#include "Memory.h" +#include + +void RandomizerCore::Randomize(std::vector& panels, int flags) { + return RandomizeRange(panels, flags, 0, panels.size()); +} + +// Range is [start, end) +void RandomizerCore::RandomizeRange(std::vector &panels, int flags, size_t startIndex, size_t endIndex) { + if (panels.size() == 0) return; + if (startIndex >= endIndex) return; + if (endIndex >= panels.size()) endIndex = panels.size(); + for (size_t i = endIndex-1; i > startIndex; i--) { + const size_t target = rand() % (i - startIndex) + startIndex; + if (i != target) { + // std::cout << "Swapping panels " << std::hex << panels[i] << " and " << std::hex << panels[target] << std::endl; + SwapPanels(panels[i], panels[target], flags); + std::swap(panels[i], panels[target]); // Panel indices in the array + } + } +} + +void RandomizerCore::SwapPanels(int panel1, int panel2, int flags) { + std::map offsets; + + if (flags & SWAP_TARGETS) { + offsets[TARGET] = sizeof(int); + } + if (flags & SWAP_LINES) { + offsets[PATH_COLOR] = 16; + offsets[REFLECTION_PATH_COLOR] = 16; + offsets[DOT_COLOR] = 16; + offsets[ACTIVE_COLOR] = 16; + offsets[BACKGROUND_REGION_COLOR] = 16; + offsets[SUCCESS_COLOR_A] = 16; + offsets[SUCCESS_COLOR_B] = 16; + offsets[STROBE_COLOR_A] = 16; + offsets[STROBE_COLOR_B] = 16; + offsets[ERROR_COLOR] = 16; + offsets[PATTERN_POINT_COLOR] = 16; + offsets[PATTERN_POINT_COLOR_A] = 16; + offsets[PATTERN_POINT_COLOR_B] = 16; + offsets[SYMBOL_A] = 16; + offsets[SYMBOL_B] = 16; + offsets[SYMBOL_C] = 16; + offsets[SYMBOL_D] = 16; + offsets[SYMBOL_E] = 16; + offsets[PUSH_SYMBOL_COLORS] = sizeof(int); + offsets[OUTER_BACKGROUND] = 16; + offsets[OUTER_BACKGROUND_MODE] = sizeof(int); + offsets[TRACED_EDGES] = 16; + offsets[AUDIO_PREFIX] = sizeof(void*); +// offsets[IS_CYLINDER] = sizeof(int); +// offsets[CYLINDER_Z0] = sizeof(float); +// offsets[CYLINDER_Z1] = sizeof(float); +// offsets[CYLINDER_RADIUS] = sizeof(float); + offsets[SPECULAR_ADD] = sizeof(float); + offsets[SPECULAR_POWER] = sizeof(int); + offsets[PATH_WIDTH_SCALE] = sizeof(float); + offsets[STARTPOINT_SCALE] = sizeof(float); + offsets[NUM_DOTS] = sizeof(int); + offsets[NUM_CONNECTIONS] = sizeof(int); + offsets[DOT_POSITIONS] = sizeof(void*); + offsets[DOT_FLAGS] = sizeof(void*); + offsets[DOT_CONNECTION_A] = sizeof(void*); + offsets[DOT_CONNECTION_B] = sizeof(void*); + offsets[DECORATIONS] = sizeof(void*); + offsets[DECORATION_FLAGS] = sizeof(void*); + offsets[DECORATION_COLORS] = sizeof(void*); + offsets[NUM_DECORATIONS] = sizeof(int); + offsets[REFLECTION_DATA] = sizeof(void*); + offsets[GRID_SIZE_X] = sizeof(int); + offsets[GRID_SIZE_Y] = sizeof(int); + offsets[STYLE_FLAGS] = sizeof(int); + offsets[SEQUENCE_LEN] = sizeof(int); + offsets[SEQUENCE] = sizeof(void*); + offsets[DOT_SEQUENCE_LEN] = sizeof(int); + offsets[DOT_SEQUENCE] = sizeof(void*); + offsets[DOT_SEQUENCE_LEN_REFLECTION] = sizeof(int); + offsets[DOT_SEQUENCE_REFLECTION] = sizeof(void*); + offsets[NUM_COLORED_REGIONS] = sizeof(int); + offsets[COLORED_REGIONS] = sizeof(void*); + offsets[PANEL_TARGET] = sizeof(void*); + offsets[SPECULAR_TEXTURE] = sizeof(void*); + } + + for (auto const& [offset, size] : offsets) { + std::vector panel1data = ReadPanelData(panel1, offset, size); + std::vector panel2data = ReadPanelData(panel2, offset, size); + WritePanelData(panel2, offset, panel1data); + WritePanelData(panel1, offset, panel2data); + } +} + +void RandomizerCore::ReassignTargets(const std::vector& panels, const std::vector& order) { + // This list is offset by 1, so the target of the Nth panel is in position N (aka the N+1th element) + // The first panel may not have a wire to power it, so we use the panel ID itself. + std::vector targetToActivatePanel = {panels[0] + 1}; + for (const int panel : panels) { + int target = ReadPanelData(panel, TARGET, 1)[0]; + targetToActivatePanel.push_back(target); + } + + for (size_t i=0; i(panels[order[i]], TARGET, {panelTarget}); + } +} -- cgit 1.4.1