From 4edd6ab796f26563368e5b8487df1f1f9bb0684c Mon Sep 17 00:00:00 2001 From: jbzdarkid Date: Thu, 25 Oct 2018 21:57:21 -0700 Subject: Some sequence randomization, and swapping some control panels. --- WitnessRandomizer/WitnessRandomizer.cpp | 175 ++++++++++++++++++++++---------- 1 file changed, 123 insertions(+), 52 deletions(-) (limited to 'WitnessRandomizer/WitnessRandomizer.cpp') diff --git a/WitnessRandomizer/WitnessRandomizer.cpp b/WitnessRandomizer/WitnessRandomizer.cpp index 2a06ee2..70e4fb2 100644 --- a/WitnessRandomizer/WitnessRandomizer.cpp +++ b/WitnessRandomizer/WitnessRandomizer.cpp @@ -1,22 +1,33 @@ /* + * BUGS: + * 3-way in treehouse not working :( + * Mountain orange is copying movement data :( + * Treehouse panels are not copying color? * FEATURES: * SWAP_TARGETS should still require the full panel sequence (and have ways to prevent softlocks?) - ** Jungle(?), Bunker, Monastery, Challenge(!), Shadows + ** Think about: Jungle + ** Hard: Monastery + ** Do: Challenge * Randomize audio logs - * List of panels which split left/right (for left/right controls) - * List of panels which split up/down (for up/down controls) * Swap sounds in jungle (along with panels) -- maybe impossible * Make orange 7 (all of oranges?) hard. Like big = hard. * Kill panel slowdown in tutorial * Fix desert elevator (laser rando) / Add keep? - * TRY: - * Swap treehouse pivots */ #include "Memory.h" #include "WitnessRandomizer.h" #include "Panels.h" #include #include +#include + +template +int find(const std::vector &data, T search, int startIndex = 0) { + for (int i=startIndex ; i({0x5B28C0, 0x18, PILLAR_L_1*8, 0x2A8}, {1.0f, 1.0f}); - - // randomizer.SwapPanels(PILLAR_L_1, PILLAR_C_L, SWAP_LINES | SWAP_STYLE | SWAP_BACK_DISTANCE); - //*/ + + // Content swaps -- must happen before squarePanels + randomizer.Randomize(upDownPanels, SWAP_LINES | SWAP_STYLE); + randomizer.Randomize(leftForwardRightPanels, SWAP_LINES | SWAP_STYLE); + + randomizer.Randomize(squarePanels, SWAP_LINES | SWAP_STYLE); + + // Frame swaps -- must happen after squarePanels + randomizer.Randomize(burnablePanels, SWAP_LINES | SWAP_STYLE); + + + // Target swaps, can happen whenever + randomizer.Randomize(lasers, SWAP_TARGETS); + + std::vector randomOrder = std::vector(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 + randomizer.RandomizeRange(randomOrder, SWAP_NONE, 1, 7); + // Randomize Pitches 1-6 onto themselves + randomizer.RandomizeRange(randomOrder, SWAP_NONE, 7, 13); + randomizer.ReassignTargets(junglePanels, randomOrder); + + randomOrder = std::vector(bunkerPanels.size(), 0); + std::iota(randomOrder.begin(), randomOrder.end(), 0); + // Randomize Tutorial 2-Advanced Tutorial 4 + Glass 1 + // Tutorial 1 cannot be randomized, since no other panel can start on + // Glass 1 will become door + glass 1, due to the targetting system + randomizer.RandomizeRange(randomOrder, SWAP_NONE, 1, 10); + // Randomize Glass 1-3 into everything after the door + int glassDoorIndex = find(randomOrder, 9) + 1; + randomizer.RandomizeRange(randomOrder, SWAP_NONE, glassDoorIndex, 12); + randomizer.ReassignTargets(bunkerPanels, randomOrder); + + randomOrder = std::vector(shadowsPanels.size(), 0); + std::iota(randomOrder.begin(), randomOrder.end(), 0); + randomizer.RandomizeRange(randomOrder, SWAP_NONE, 0, 8); // Tutorial + randomizer.RandomizeRange(randomOrder, SWAP_NONE, 8, 16); // Avoid + randomizer.RandomizeRange(randomOrder, SWAP_NONE, 16, 21); // Follow + randomizer.ReassignTargets(shadowsPanels, randomOrder); + randomizer.TurnOff(shadowsPanels[0]); + randomizer.TurnOn(shadowsPanels[randomOrder[0]]); } WitnessRandomizer::WitnessRandomizer() : _memory("witness64_d3d11.exe") { // Turn off desert flood final - _memory.WriteData({0x5B28C0, 0x18, 0x18076*8, 0x2A8}, {0.0f, 0.0f}); + TurnOff(0x18076); // Change desert floating target to desert flood final _memory.WriteData({0x5B28C0, 0x18, 0x17ECA*8, 0x2BC}, {0x18077}); // Distance-gate shadows laser to prevent sniping through the bars - _memory.WriteData({0x5B28C0, 0x18, 0x19650*8, 0x3C0}, {2.0f}); + _memory.WriteData({0x5B28C0, 0x18, 0x19650*8, 0x3C0}, {2.5f}); + // Change the shadows tutorial cable to only activate avoid + _memory.WriteData({0x5B28C0, 0x18, 0x319A8*8, 0xD8}, {0}); + // Change shadows avoid 8 to power shadows follow + _memory.WriteData({0x5B28C0, 0x18, 0x1972F*8, 0x2BC}, {0x1C34C}); + // Disable tutorial cursor speed modifications + _memory.WriteData({0x5B28C0, 0x18, 0x00295*8, 0x358}, {1.0}); + _memory.WriteData({0x5B28C0, 0x18, 0x0C373*8, 0x358}, {1.0}); + _memory.WriteData({0x5B28C0, 0x18, 0x00293*8, 0x358}, {1.0}); + _memory.WriteData({0x5B28C0, 0x18, 0x002C2*8, 0x358}, {1.0}); + + // Explicitly set back-off distance for the challenge entry & final 2 pillars // _memory.WriteData({0x5B28C0, 0x18, 0x9DD5*8, 0x22C}, {2.5f}); @@ -85,10 +111,17 @@ WitnessRandomizer::WitnessRandomizer() : _memory("witness64_d3d11.exe") // _memory.WriteData({0x5B28C0, 0x18, 0x1C319*8, 0x22C}, {3.0f}); } -void WitnessRandomizer::Randomize(std::vector panels, int flags) { +void WitnessRandomizer::Randomize(std::vector &panels, int flags) { + return RandomizeRange(panels, flags, 0, panels.size()); +} + +// Range is [start, end) +void WitnessRandomizer::RandomizeRange(std::vector &panels, int flags, size_t startIndex, size_t endIndex) { if (panels.size() == 0) return; - for (size_t i=panels.size() - 1; i > 1; i--) { - int target = rand() % i; + if (startIndex >= endIndex) return; + if (endIndex >= panels.size()) endIndex = panels.size(); + for (size_t i = endIndex-1; i > startIndex+1; i--) { + 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); @@ -180,6 +213,36 @@ void WitnessRandomizer::SwapPanels(int panel1, int panel2, int flags) { } } +/* +void WitnessRandomizer::SwapTargetList(const std::vector& initialOrder, const std::vector& randomizedOrder) { + std::vector> randomizedTargets; + for (int panel : randomizedOrder) { + randomizedTargets.push_back(_memory.ReadData({0x5B28C0, 0x18, panel*8, 0x2BC}, 1)); + } + for (int i=0; i target = randomizedTargets[i]; + _memory.WriteData({0x5B28C0, 0x18, panel*8, 0x2BC}, target); + } +} +*/ + +void WitnessRandomizer::ReassignTargets(const std::vector& panels, const std::vector& order) { + std::vector targetToActivatePanel = {panels[0] + 1}; + for (int panel : panels) { + int target = _memory.ReadData({0x5B28C0, 0x18, panel*8, 0x2BC}, 1)[0]; + targetToActivatePanel.push_back(target); + } + + for (int i=0; i({0x5B28C0, 0x18, panels[order[i]]*8, 0x2BC}, {panelTarget}); + } +} + void WitnessRandomizer::SwapPanelData(int panel1, int panel2, int finalOffset, int dataSize) { // Currently wired for old version std::vector panel1Offset = {0x5B28C0, 0x18, panel1*8, finalOffset}; @@ -191,3 +254,11 @@ void WitnessRandomizer::SwapPanelData(int panel1, int panel2, int finalOffset, i _memory.WriteData(panel2Offset, panel1Data); _memory.WriteData(panel1Offset, panel2Data); } + +void WitnessRandomizer::TurnOn(int panel) { + _memory.WriteData({0x5B28C0, 0x18, panel*8, 0x2A8}, {1.0f, 1.0f}); +} + +void WitnessRandomizer::TurnOff(int panel) { + _memory.WriteData({0x5B28C0, 0x18, panel*8, 0x2A8}, {0.0f, 0.0f}); +} -- cgit 1.4.1