diff options
author | jbzdarkid <jbzdarkid@gmail.com> | 2018-10-28 15:44:50 -0700 |
---|---|---|
committer | jbzdarkid <jbzdarkid@gmail.com> | 2018-10-28 15:44:50 -0700 |
commit | d99313f4e4fdf5103c5f149e2d54dbf6e4fcc3f2 (patch) | |
tree | 6700a1094c3d42812f1bdca64d7df3dbc07fce37 /Source | |
parent | 5fb764e4b5cd603c63e638f912a4c39772db8480 (diff) | |
download | witness-tutorializer-d99313f4e4fdf5103c5f149e2d54dbf6e4fcc3f2.tar.gz witness-tutorializer-d99313f4e4fdf5103c5f149e2d54dbf6e4fcc3f2.tar.bz2 witness-tutorializer-d99313f4e4fdf5103c5f149e2d54dbf6e4fcc3f2.zip |
Fix treehouse pivots, jungle + monastery randomization, add final pillars randomization
Diffstat (limited to 'Source')
-rw-r--r-- | Source/Panels.h | 87 | ||||
-rw-r--r-- | Source/Randomizer.cpp | 286 | ||||
-rw-r--r-- | Source/Randomizer.h | 168 | ||||
-rw-r--r-- | Source/RandomizerCore.cpp | 119 | ||||
-rw-r--r-- | Source/RandomizerCore.h | 155 |
5 files changed, 428 insertions, 387 deletions
diff --git a/Source/Panels.h b/Source/Panels.h index e070005..b3a7791 100644 --- a/Source/Panels.h +++ b/Source/Panels.h | |||
@@ -17,50 +17,6 @@ std::vector<int> lasers = { | |||
17 | 0x19650, // Shadows | 17 | 0x19650, // Shadows |
18 | }; | 18 | }; |
19 | 19 | ||
20 | // Note: Some of these (non-desert) are duplicated elsewhere | ||
21 | std::vector<int> burnablePanels = { | ||
22 | 0x17D9C, // Treehouse Yellow 7 | ||
23 | 0x17DC2, // Treehouse Yellow 8 | ||
24 | 0x17DC4, // Treehouse Yellow 9 | ||
25 | 0x00999, // Swamp Discontinuous 1 | ||
26 | 0x0099D, // Swamp Discontinuous 2 | ||
27 | 0x009A0, // Swamp Discontinuous 3 | ||
28 | 0x009A1, // Swamp Discontinuous 4 | ||
29 | 0x00007, // Swamp Rotation Tutorial 1 | ||
30 | 0x00008, // Swamp Rotation Tutorial 2 | ||
31 | 0x00009, // Swamp Rotation Tutorial 3 | ||
32 | 0x0000A, // Swamp Rotation Tutorial 4 | ||
33 | 0x28AC7, // Town Blue 1 | ||
34 | 0x28AC8, // Town Blue 2 | ||
35 | 0x28ACA, // Town Blue 3 | ||
36 | 0x28ACB, // Town Blue 4 | ||
37 | 0x28ACC, // Town Blue 5 | ||
38 | 0x17CF0, // Mill Discard | ||
39 | |||
40 | 0x00698, // Desert Surface 1 | ||
41 | 0x0048F, // Desert Surface 2 | ||
42 | 0x09F92, // Desert Surface 3 | ||
43 | 0x0A036, // Desert Surface 4 | ||
44 | 0x09DA6, // Desert Surface 5 | ||
45 | 0x0A049, // Desert Surface 6 | ||
46 | 0x0A053, // Desert Surface 7 | ||
47 | 0x09F94, // Desert Surface 8 | ||
48 | 0x00422, // Desert Light 1 | ||
49 | 0x006E3, // Desert Light 2 | ||
50 | 0x0A02D, // Desert Light 3 | ||
51 | 0x00C72, // Desert Pond 1 | ||
52 | 0x0129D, // Desert Pond 2 | ||
53 | 0x008BB, // Desert Pond 3 | ||
54 | 0x0078D, // Desert Pond 4 | ||
55 | 0x18313, // Desert Pond 5 | ||
56 | 0x04D18, // Desert Flood 1 | ||
57 | 0x01205, // Desert Flood 2 | ||
58 | 0x181AB, // Desert Flood 3 | ||
59 | 0x0117A, // Desert Flood 4 | ||
60 | 0x17ECA, // Desert Flood 5 | ||
61 | 0x012D7, // Desert Final Far | ||
62 | }; | ||
63 | |||
64 | // Note: Some of these (non-controls) are duplicated elsewhere | 20 | // Note: Some of these (non-controls) are duplicated elsewhere |
65 | // TODO: Gave up | 21 | // TODO: Gave up |
66 | std::vector<int> leftRightPanels = { | 22 | std::vector<int> leftRightPanels = { |
@@ -105,10 +61,10 @@ std::vector<int> upDownPanels = { | |||
105 | 61 | ||
106 | // Note: Some of these (non-controls) are duplicated elsewhere | 62 | // Note: Some of these (non-controls) are duplicated elsewhere |
107 | std::vector<int> leftForwardRightPanels = { | 63 | std::vector<int> leftForwardRightPanels = { |
108 | // 0x00075, // Symmetry Island Colored Dots 3 | 64 | 0x00075, // Symmetry Island Colored Dots 3 |
109 | // 0x288EA, // UTM Perspective 1 | 65 | 0x288EA, // UTM Perspective 1 |
110 | // 0x288FC, // UTM Perspective 2 | 66 | 0x288FC, // UTM Perspective 2 |
111 | // 0x289E7, // UTM Perspective 3 | 67 | 0x289E7, // UTM Perspective 3 |
112 | 68 | ||
113 | 0x17DD1, // Treehouse Left Orange 9 | 69 | 0x17DD1, // Treehouse Left Orange 9 |
114 | 0x17CE3, // Treehouse Right Orange 4 | 70 | 0x17CE3, // Treehouse Right Orange 4 |
@@ -458,6 +414,35 @@ std::vector<int> squarePanels = { | |||
458 | 0x09E85, // Tunnels Town Shortcut | 414 | 0x09E85, // Tunnels Town Shortcut |
459 | }; | 415 | }; |
460 | 416 | ||
417 | std::vector<int> desertPanels = { | ||
418 | 0x00698, // Desert Surface 1 | ||
419 | 0x0048F, // Desert Surface 2 | ||
420 | 0x09F92, // Desert Surface 3 | ||
421 | 0x0A036, // Desert Surface 4 | ||
422 | 0x09DA6, // Desert Surface 5 | ||
423 | 0x0A049, // Desert Surface 6 | ||
424 | 0x0A053, // Desert Surface 7 | ||
425 | 0x09F94, // Desert Surface 8 | ||
426 | 0x00422, // Desert Light 1 | ||
427 | 0x006E3, // Desert Light 2 | ||
428 | 0x0A02D, // Desert Light 3 | ||
429 | 0x00C72, // Desert Pond 1 | ||
430 | 0x0129D, // Desert Pond 2 | ||
431 | 0x008BB, // Desert Pond 3 | ||
432 | 0x0078D, // Desert Pond 4 | ||
433 | 0x18313, // Desert Pond 5 | ||
434 | 0x04D18, // Desert Flood 1 | ||
435 | 0x01205, // Desert Flood 2 | ||
436 | 0x181AB, // Desert Flood 3 | ||
437 | 0x0117A, // Desert Flood 4 | ||
438 | 0x17ECA, // Desert Flood 5 | ||
439 | // 0x18076, // Desert Flood Exit | ||
440 | // 0x0A15C, // Desert Final Left Convex | ||
441 | // 0x09FFF, // Desert Final Left Concave | ||
442 | // 0x0A15F, // Desert Final Near | ||
443 | 0x012D7, // Desert Final Far | ||
444 | }; | ||
445 | |||
461 | std::vector<int> shadowsPanels = { | 446 | std::vector<int> shadowsPanels = { |
462 | 0x198B5, // Shadows Tutorial 1 | 447 | 0x198B5, // Shadows Tutorial 1 |
463 | 0x198BD, // Shadows Tutorial 2 | 448 | 0x198BD, // Shadows Tutorial 2 |
@@ -485,8 +470,8 @@ std::vector<int> shadowsPanels = { | |||
485 | 470 | ||
486 | std::vector<int> monasteryPanels = { | 471 | std::vector<int> monasteryPanels = { |
487 | 0x00B10, // Monastery Left Door | 472 | 0x00B10, // Monastery Left Door |
488 | 0x00290, // Monastery Exterior 1 | ||
489 | 0x00C92, // Monastery Right Door | 473 | 0x00C92, // Monastery Right Door |
474 | 0x00290, // Monastery Exterior 1 | ||
490 | 0x00038, // Monastery Exterior 2 | 475 | 0x00038, // Monastery Exterior 2 |
491 | 0x00037, // Monastery Exterior 3 | 476 | 0x00037, // Monastery Exterior 3 |
492 | // 0x09D9B, // Monastery Bonsai | 477 | // 0x09D9B, // Monastery Bonsai |
@@ -616,10 +601,6 @@ std::vector<int> nothingPanels = { | |||
616 | 0x0C335, // Tutorial Pillar | 601 | 0x0C335, // Tutorial Pillar |
617 | 0x0C373, // Tutorial Patio floor | 602 | 0x0C373, // Tutorial Patio floor |
618 | 0x1C349, // Symmetry Island Door 2 - Collision fails here, sadly | 603 | 0x1C349, // Symmetry Island Door 2 - Collision fails here, sadly |
619 | 0x18076, // Desert Flood Exit - I am doing something with this -- but it's a very unique panel. | ||
620 | 0x0A15C, // Desert Final Left Convex | ||
621 | 0x09FFF, // Desert Final Left Concave | ||
622 | 0x0A15F, // Desert Final Near | ||
623 | 0x033EA, // Keep Yellow Pressure Plates | 604 | 0x033EA, // Keep Yellow Pressure Plates |
624 | 0x0A3A8, // Keep Yellow Reset | 605 | 0x0A3A8, // Keep Yellow Reset |
625 | 0x01BE9, // Keep Purple Pressure Plates | 606 | 0x01BE9, // Keep Purple Pressure Plates |
diff --git a/Source/Randomizer.cpp b/Source/Randomizer.cpp index b8462e5..8c4297d 100644 --- a/Source/Randomizer.cpp +++ b/Source/Randomizer.cpp | |||
@@ -2,15 +2,10 @@ | |||
2 | * TODO: Split out main() logic into another file, and move into separate functions for easier testing. Then write tests. | 2 | * TODO: Split out main() logic into another file, and move into separate functions for easier testing. Then write tests. |
3 | * BUGS: | 3 | * BUGS: |
4 | * Shipwreck vault fails, possibly because of dot_reflection? Sometimes? | 4 | * Shipwreck vault fails, possibly because of dot_reflection? Sometimes? |
5 | * Treehouse pivots *should* work, but I need to not copy style_flags. | ||
6 | This seems to cause crashes when pivots appear elsewhere in the world. | ||
7 | * Some panels are impossible casually: (idc, I think) | 5 | * Some panels are impossible casually: (idc, I think) |
8 | ** Town Stars, Invisible dots | 6 | ** Town Stars, Invisible dots |
9 | * Something is wrong with jungle re: softlocks | ||
10 | * FEATURES: | 7 | * FEATURES: |
11 | * SWAP_TARGETS should still require the full panel sequence (and have ways to prevent softlocks?) | 8 | * SWAP_TARGETS should still require the full panel sequence (and have ways to prevent softlocks?) |
12 | ** Think about: Jungle | ||
13 | ** Hard: Monastery | ||
14 | ** Do: Challenge | 9 | ** Do: Challenge |
15 | * Randomize audio logs | 10 | * Randomize audio logs |
16 | * Swap sounds in jungle (along with panels) -- maybe impossible | 11 | * Swap sounds in jungle (along with panels) -- maybe impossible |
@@ -28,212 +23,139 @@ | |||
28 | #include <chrono> | 23 | #include <chrono> |
29 | 24 | ||
30 | template <class T> | 25 | template <class T> |
31 | size_t find(const std::vector<T> &data, T search, size_t startIndex = 0) { | 26 | int find(const std::vector<T> &data, T search, size_t startIndex = 0) { |
32 | for (size_t i=startIndex ; i<data.size(); i++) { | 27 | for (size_t i=startIndex ; i<data.size(); i++) { |
33 | if (data[i] == search) return i; | 28 | if (data[i] == search) return static_cast<int>(i); |
34 | } | 29 | } |
35 | std::cout << "Couldn't find " << search << " in data!" << std::endl; | 30 | std::cout << "Couldn't find " << search << " in data!" << std::endl; |
36 | exit(-1); | 31 | exit(-1); |
37 | } | 32 | } |
38 | 33 | ||
39 | void Randomizer::Randomize(int seed) | 34 | void Randomizer::Randomize() |
40 | { | 35 | { |
41 | // Content swaps -- must happen before squarePanels | 36 | // Content swaps -- must happen before squarePanels |
42 | Randomize(tallUpDownPanels, SWAP_LINES | SWAP_STYLE); | 37 | _core.Randomize(tallUpDownPanels, SWAP_LINES|SWAP_LINES); |
43 | Randomize(upDownPanels, SWAP_LINES | SWAP_STYLE); | 38 | _core.Randomize(upDownPanels, SWAP_LINES|SWAP_LINES); |
44 | Randomize(leftForwardRightPanels, SWAP_LINES); | 39 | _core.Randomize(leftForwardRightPanels, SWAP_LINES|SWAP_LINES); |
45 | 40 | ||
46 | Randomize(squarePanels, SWAP_LINES | SWAP_STYLE); | 41 | _core.Randomize(squarePanels, SWAP_LINES|SWAP_LINES); |
47 | 42 | ||
48 | // Frame swaps -- must happen after squarePanels | 43 | // Individual area modifications |
49 | Randomize(burnablePanels, SWAP_LINES | SWAP_STYLE); | 44 | RandomizeTutorial(); |
45 | RandomizeSymmetry(); | ||
46 | RandomizeDesert(); | ||
47 | RandomizeQuarry(); | ||
48 | RandomizeTreehouse(); | ||
49 | RandomizeKeep(); | ||
50 | RandomizeShadows(); | ||
51 | RandomizeTown(); | ||
52 | RandomizeMonastery(); | ||
53 | RandomizeBunker(); | ||
54 | RandomizeJungle(); | ||
55 | RandomizeSwamp(); | ||
56 | RandomizeMountain(); | ||
57 | } | ||
50 | 58 | ||
51 | // Target swaps, can happen whenever | 59 | void Randomizer::RandomizeTutorial() { |
52 | Randomize(lasers, SWAP_TARGETS); | 60 | // Disable tutorial cursor speed modifications (not working?) |
53 | // Read the target of keep front laser, and write it to keep back laser. | 61 | _core.WritePanelData<float>(0x00295, CURSOR_SPEED_SCALE, {1.0}); |
54 | std::vector<int> keepFrontLaserTarget = ReadPanelData<int>(0x0360E, TARGET, 1); | 62 | _core.WritePanelData<float>(0x0C373, CURSOR_SPEED_SCALE, {1.0}); |
55 | WritePanelData<int>(0x03317, TARGET, keepFrontLaserTarget); | 63 | _core.WritePanelData<float>(0x00293, CURSOR_SPEED_SCALE, {1.0}); |
64 | _core.WritePanelData<float>(0x002C2, CURSOR_SPEED_SCALE, {1.0}); | ||
65 | } | ||
56 | 66 | ||
57 | std::vector<int> randomOrder; | 67 | void Randomizer::RandomizeSymmetry() { |
68 | } | ||
58 | 69 | ||
59 | /* Jungle | 70 | void Randomizer::RandomizeDesert() { |
60 | randomOrder = std::vector(junglePanels.size(), 0); | 71 | _core.Randomize(desertPanels, SWAP_LINES|SWAP_LINES); |
61 | std::iota(randomOrder.begin(), randomOrder.end(), 0); | ||
62 | // Randomize Waves 2-7 | ||
63 | // Waves 1 cannot be randomized, since no other panel can start on | ||
64 | randomizer.RandomizeRange(randomOrder, SWAP_NONE, 1, 7); | ||
65 | // Randomize Pitches 1-6 onto themselves | ||
66 | randomizer.RandomizeRange(randomOrder, SWAP_NONE, 7, 13); | ||
67 | randomizer.ReassignTargets(junglePanels, randomOrder); | ||
68 | */ | ||
69 | 72 | ||
70 | /* Bunker */ | 73 | // Turn off desert surface 8 |
71 | randomOrder = std::vector(bunkerPanels.size(), 0); | 74 | _core.WritePanelData<float>(0x09F94, POWER, {0.0, 0.0}); |
72 | std::iota(randomOrder.begin(), randomOrder.end(), 0); | 75 | // Turn off desert flood final |
73 | // Randomize Tutorial 2-Advanced Tutorial 4 + Glass 1 | 76 | _core.WritePanelData<float>(0x18076, POWER, {0.0, 0.0}); |
74 | // Tutorial 1 cannot be randomized, since no other panel can start on | 77 | // Change desert floating target to desert flood final |
75 | // Glass 1 will become door + glass 1, due to the targetting system | 78 | _core.WritePanelData<int>(0x17ECA, TARGET, {0x18077}); |
76 | RandomizeRange(randomOrder, SWAP_NONE, 1, 10); | 79 | } |
77 | // Randomize Glass 1-3 into everything after the door | ||
78 | const size_t glassDoorIndex = find(randomOrder, 9) + 1; | ||
79 | RandomizeRange(randomOrder, SWAP_NONE, glassDoorIndex, 12); | ||
80 | ReassignTargets(bunkerPanels, randomOrder); | ||
81 | |||
82 | /* Shadows */ | ||
83 | randomOrder = std::vector(shadowsPanels.size(), 0); | ||
84 | std::iota(randomOrder.begin(), randomOrder.end(), 0); | ||
85 | RandomizeRange(randomOrder, SWAP_NONE, 0, 8); // Tutorial | ||
86 | RandomizeRange(randomOrder, SWAP_NONE, 8, 16); // Avoid | ||
87 | RandomizeRange(randomOrder, SWAP_NONE, 16, 21); // Follow | ||
88 | ReassignTargets(shadowsPanels, randomOrder); | ||
89 | // Turn off original starting panel | ||
90 | WritePanelData<float>(shadowsPanels[0], POWER, {0.0f, 0.0f}); | ||
91 | // Turn on new starting panel | ||
92 | WritePanelData<float>(shadowsPanels[randomOrder[0]], POWER, {1.0f, 1.0f}); | ||
93 | 80 | ||
94 | /* Monastery | 81 | void Randomizer::RandomizeQuarry() { |
95 | randomOrder = std::vector(monasteryPanels.size(), 0); | 82 | } |
96 | std::iota(randomOrder.begin(), randomOrder.end(), 0); | ||
97 | randomizer.RandomizeRange(randomOrder, SWAP_NONE, 2, 6); // outer 2 & 3, inner 1 | ||
98 | // Once outer 3 and right door are solved, inner 2-4 are accessible | ||
99 | int innerPanelsIndex = max(find(randomOrder, 2), find(randomOrder, 4)); | ||
100 | randomizer.RandomizeRange(randomOrder, SWAP_NONE, innerPanelsIndex, 9); // Inner 2-4 | ||
101 | 83 | ||
102 | randomizer.ReassignTargets(monasteryPanels, randomOrder); | 84 | void Randomizer::RandomizeTreehouse() { |
103 | */ | 85 | // Ensure that whatever pivot panels we have are flagged as "pivotable" |
86 | _core.WritePanelData<int>(0x17DD1, STYLE_FLAGS, {0x8000}); | ||
87 | _core.WritePanelData<int>(0x17CE3, STYLE_FLAGS, {0x8000}); | ||
88 | _core.WritePanelData<int>(0x17DB7, STYLE_FLAGS, {0x8000}); | ||
89 | _core.WritePanelData<int>(0x17E52, STYLE_FLAGS, {0x8000}); | ||
104 | } | 90 | } |
105 | 91 | ||
106 | Randomizer::Randomizer() | 92 | void Randomizer::RandomizeKeep() { |
107 | { | 93 | } |
108 | // Turn off desert surface 8 | ||
109 | WritePanelData<float>(0x09F94, POWER, {0.0, 0.0}); | ||
110 | // Turn off desert flood final | ||
111 | WritePanelData<float>(0x18076, POWER, {0.0, 0.0}); | ||
112 | // Change desert floating target to desert flood final | ||
113 | WritePanelData<int>(0x17ECA, TARGET, {0x18077}); | ||
114 | 94 | ||
95 | void Randomizer::RandomizeShadows() { | ||
115 | // Distance-gate shadows laser to prevent sniping through the bars | 96 | // Distance-gate shadows laser to prevent sniping through the bars |
116 | WritePanelData<float>(0x19650, MAX_BROADCAST_DISTANCE, {2.5}); | 97 | _core.WritePanelData<float>(0x19650, MAX_BROADCAST_DISTANCE, {2.5}); |
117 | // Change the shadows tutorial cable to only activate avoid | 98 | // Change the shadows tutorial cable to only activate avoid |
118 | WritePanelData<int>(0x319A8, CABLE_TARGET_2, {0}); | 99 | _core.WritePanelData<int>(0x319A8, CABLE_TARGET_2, {0}); |
119 | // Change shadows avoid 8 to power shadows follow | 100 | // Change shadows avoid 8 to power shadows follow |
120 | WritePanelData<int>(0x1972F, TARGET, {0x1C34C}); | 101 | _core.WritePanelData<int>(0x1972F, TARGET, {0x1C34C}); |
121 | |||
122 | // Distance-gate swamp snipe 1 to prevent RNG swamp snipe | ||
123 | WritePanelData<float>(0x17C05, MAX_BROADCAST_DISTANCE, {5.0}); | ||
124 | 102 | ||
125 | // Disable tutorial cursor speed modifications (not working?) | 103 | std::vector<int> randomOrder(shadowsPanels.size(), 0); |
126 | WritePanelData<float>(0x00295, CURSOR_SPEED_SCALE, {1.0}); | 104 | std::iota(randomOrder.begin(), randomOrder.end(), 0); |
127 | WritePanelData<float>(0x0C373, CURSOR_SPEED_SCALE, {1.0}); | 105 | _core.RandomizeRange(randomOrder, SWAP_NONE, 0, 8); // Tutorial |
128 | WritePanelData<float>(0x00293, CURSOR_SPEED_SCALE, {1.0}); | 106 | _core.RandomizeRange(randomOrder, SWAP_NONE, 8, 16); // Avoid |
129 | WritePanelData<float>(0x002C2, CURSOR_SPEED_SCALE, {1.0}); | 107 | _core.RandomizeRange(randomOrder, SWAP_NONE, 16, 21); // Follow |
108 | _core.ReassignTargets(shadowsPanels, randomOrder); | ||
109 | // Turn off original starting panel | ||
110 | _core.WritePanelData<float>(shadowsPanels[0], POWER, {0.0f, 0.0f}); | ||
111 | // Turn on new starting panel | ||
112 | _core.WritePanelData<float>(shadowsPanels[randomOrder[0]], POWER, {1.0f, 1.0f}); | ||
130 | } | 113 | } |
131 | 114 | ||
132 | void Randomizer::Randomize(std::vector<int>& panels, int flags) { | 115 | void Randomizer::RandomizeTown() { |
133 | return RandomizeRange(panels, flags, 0, panels.size()); | ||
134 | } | 116 | } |
135 | 117 | ||
136 | // Range is [start, end) | 118 | void Randomizer::RandomizeMonastery() { |
137 | void Randomizer::RandomizeRange(std::vector<int> &panels, int flags, size_t startIndex, size_t endIndex) { | 119 | std::vector<int> randomOrder(monasteryPanels.size(), 0); |
138 | if (panels.size() == 0) return; | 120 | std::iota(randomOrder.begin(), randomOrder.end(), 0); |
139 | if (startIndex >= endIndex) return; | 121 | _core.RandomizeRange(randomOrder, SWAP_NONE, 3, 9); // Outer 2 & 3, Inner 1-4 |
140 | if (endIndex >= panels.size()) endIndex = panels.size(); | 122 | _core.ReassignTargets(monasteryPanels, randomOrder); |
141 | for (size_t i = endIndex-1; i > startIndex+1; i--) { | ||
142 | const size_t target = rand() % (i - startIndex) + startIndex; | ||
143 | if (i != target) { | ||
144 | // std::cout << "Swapping panels " << std::hex << panels[i] << " and " << std::hex << panels[target] << std::endl; | ||
145 | SwapPanels(panels[i], panels[target], flags); | ||
146 | std::swap(panels[i], panels[target]); // Panel indices in the array | ||
147 | } | ||
148 | } | ||
149 | } | 123 | } |
150 | 124 | ||
151 | void Randomizer::SwapPanels(int panel1, int panel2, int flags) { | 125 | void Randomizer::RandomizeBunker() { |
152 | std::map<int, int> offsets; | 126 | std::vector<int> randomOrder(bunkerPanels.size(), 0); |
127 | std::iota(randomOrder.begin(), randomOrder.end(), 0); | ||
128 | // Randomize Tutorial 2-Advanced Tutorial 4 + Glass 1 | ||
129 | // Tutorial 1 cannot be randomized, since no other panel can start on | ||
130 | // Glass 1 will become door + glass 1, due to the targetting system | ||
131 | _core.RandomizeRange(randomOrder, SWAP_NONE, 1, 10); | ||
132 | // Randomize Glass 1-3 into everything after the door/glass 1 | ||
133 | const size_t glass1Index = find(randomOrder, 9); | ||
134 | _core.RandomizeRange(randomOrder, SWAP_NONE, glass1Index + 1, 12); | ||
135 | _core.ReassignTargets(bunkerPanels, randomOrder); | ||
136 | } | ||
153 | 137 | ||
154 | if (flags & SWAP_TARGETS) { | 138 | void Randomizer::RandomizeJungle() { |
155 | offsets[TARGET] = sizeof(int); | 139 | std::vector<int> randomOrder(junglePanels.size(), 0); |
156 | } | 140 | std::iota(randomOrder.begin(), randomOrder.end(), 0); |
157 | if (flags & SWAP_STYLE) { | 141 | // Randomize Waves 2-7 |
158 | offsets[STYLE_FLAGS] = sizeof(int); | 142 | // Waves 1 cannot be randomized, since no other panel can start on |
159 | } | 143 | _core.RandomizeRange(randomOrder, SWAP_NONE, 1, 7); |
160 | if (flags & SWAP_LINES) { | 144 | // Randomize Pitches 1-6 onto themselves |
161 | offsets[PATH_COLOR] = 16; | 145 | _core.RandomizeRange(randomOrder, SWAP_NONE, 8, 13); |
162 | offsets[REFLECTION_PATH_COLOR] = 16; | 146 | _core.ReassignTargets(junglePanels, randomOrder); |
163 | offsets[DOT_COLOR] = 16; | 147 | } |
164 | offsets[ACTIVE_COLOR] = 16; | ||
165 | offsets[BACKGROUND_REGION_COLOR] = 16; | ||
166 | offsets[SUCCESS_COLOR_A] = 16; | ||
167 | offsets[SUCCESS_COLOR_B] = 16; | ||
168 | offsets[STROBE_COLOR_A] = 16; | ||
169 | offsets[STROBE_COLOR_B] = 16; | ||
170 | offsets[ERROR_COLOR] = 16; | ||
171 | offsets[PATTERN_POINT_COLOR] = 16; | ||
172 | offsets[PATTERN_POINT_COLOR_A] = 16; | ||
173 | offsets[PATTERN_POINT_COLOR_B] = 16; | ||
174 | offsets[SYMBOL_A] = 16; | ||
175 | offsets[SYMBOL_B] = 16; | ||
176 | offsets[SYMBOL_C] = 16; | ||
177 | offsets[SYMBOL_D] = 16; | ||
178 | offsets[SYMBOL_E] = 16; | ||
179 | offsets[PUSH_SYMBOL_COLORS] = sizeof(int); | ||
180 | offsets[OUTER_BACKGROUND] = 16; | ||
181 | offsets[OUTER_BACKGROUND_MODE] = sizeof(int); | ||
182 | offsets[TRACED_EDGES] = 16; | ||
183 | offsets[AUDIO_PREFIX] = sizeof(void*); | ||
184 | // offsets[IS_CYLINDER] = sizeof(int); | ||
185 | // offsets[CYLINDER_Z0] = sizeof(float); | ||
186 | // offsets[CYLINDER_Z1] = sizeof(float); | ||
187 | // offsets[CYLINDER_RADIUS] = sizeof(float); | ||
188 | offsets[SPECULAR_ADD] = sizeof(float); | ||
189 | offsets[SPECULAR_POWER] = sizeof(int); | ||
190 | offsets[PATH_WIDTH_SCALE] = sizeof(float); | ||
191 | offsets[STARTPOINT_SCALE] = sizeof(float); | ||
192 | offsets[NUM_DOTS] = sizeof(int); | ||
193 | offsets[NUM_CONNECTIONS] = sizeof(int); | ||
194 | offsets[DOT_POSITIONS] = sizeof(void*); | ||
195 | offsets[DOT_FLAGS] = sizeof(void*); | ||
196 | offsets[DOT_CONNECTION_A] = sizeof(void*); | ||
197 | offsets[DOT_CONNECTION_B] = sizeof(void*); | ||
198 | offsets[DECORATIONS] = sizeof(void*); | ||
199 | offsets[DECORATION_FLAGS] = sizeof(void*); | ||
200 | offsets[DECORATION_COLORS] = sizeof(void*); | ||
201 | offsets[NUM_DECORATIONS] = sizeof(int); | ||
202 | offsets[REFLECTION_DATA] = sizeof(void*); | ||
203 | offsets[GRID_SIZE_X] = sizeof(int); | ||
204 | offsets[GRID_SIZE_Y] = sizeof(int); | ||
205 | offsets[SEQUENCE_LEN] = sizeof(int); | ||
206 | offsets[SEQUENCE] = sizeof(void*); | ||
207 | offsets[DOT_SEQUENCE_LEN] = sizeof(int); | ||
208 | offsets[DOT_SEQUENCE] = sizeof(void*); | ||
209 | offsets[DOT_SEQUENCE_LEN_REFLECTION] = sizeof(int); | ||
210 | offsets[DOT_SEQUENCE_REFLECTION] = sizeof(void*); | ||
211 | offsets[NUM_COLORED_REGIONS] = sizeof(int); | ||
212 | offsets[COLORED_REGIONS] = sizeof(void*); | ||
213 | offsets[PANEL_TARGET] = sizeof(void*); | ||
214 | offsets[SPECULAR_TEXTURE] = sizeof(void*); | ||
215 | } | ||
216 | 148 | ||
217 | for (auto const& [offset, size] : offsets) { | 149 | void Randomizer::RandomizeSwamp() { |
218 | std::vector<byte> panel1data = ReadPanelData<byte>(panel1, offset, size); | 150 | // Distance-gate swamp snipe 1 to prevent RNG swamp snipe |
219 | std::vector<byte> panel2data = ReadPanelData<byte>(panel2, offset, size); | 151 | _core.WritePanelData<float>(0x17C05, MAX_BROADCAST_DISTANCE, {15.0}); |
220 | WritePanelData<byte>(panel2, offset, panel1data); | ||
221 | WritePanelData<byte>(panel1, offset, panel2data); | ||
222 | } | ||
223 | } | 152 | } |
224 | 153 | ||
225 | void Randomizer::ReassignTargets(const std::vector<int>& panels, const std::vector<int>& order) { | 154 | void Randomizer::RandomizeMountain() { |
226 | // This list is offset by 1, so the target of the Nth panel is in position N (aka the N+1th element) | 155 | _core.Randomize(lasers, SWAP_TARGETS); |
227 | // The first panel may not have a wire to power it, so we use the panel ID itself. | 156 | _core.Randomize(pillars, SWAP_LINES|SWAP_LINES); |
228 | std::vector<int> targetToActivatePanel = {panels[0] + 1}; | ||
229 | for (const int panel : panels) { | ||
230 | int target = ReadPanelData<int>(panel, TARGET, 1)[0]; | ||
231 | targetToActivatePanel.push_back(target); | ||
232 | } | ||
233 | 157 | ||
234 | for (size_t i=0; i<order.size() - 1; i++) { | 158 | // Read the target of keep front laser, and write it to keep back laser. |
235 | // Set the target of order[i] to order[i+1], using the "real" target as determined above. | 159 | std::vector<int> keepFrontLaserTarget = _core.ReadPanelData<int>(0x0360E, TARGET, 1); |
236 | const int panelTarget = targetToActivatePanel[order[i+1]]; | 160 | _core.WritePanelData<int>(0x03317, TARGET, keepFrontLaserTarget); |
237 | WritePanelData<int>(panels[order[i]], TARGET, {panelTarget}); | 161 | } \ No newline at end of file |
238 | } | ||
239 | } | ||
diff --git a/Source/Randomizer.h b/Source/Randomizer.h index 6615e31..861f5a2 100644 --- a/Source/Randomizer.h +++ b/Source/Randomizer.h | |||
@@ -1,159 +1,23 @@ | |||
1 | #pragma once | 1 | #pragma once |
2 | #include "Memory.h" | 2 | #include "RandomizerCore.h" |
3 | |||
4 | // #define GLOBALS 0x5B28C0 | ||
5 | #define GLOBALS 0x62A080 | ||
6 | |||
7 | __declspec(selectany) int SWAP_NONE = 0x0; | ||
8 | __declspec(selectany) int SWAP_TARGETS = 0x1; | ||
9 | __declspec(selectany) int SWAP_LINES = 0x2; | ||
10 | __declspec(selectany) int SWAP_STYLE = 0x4; | ||
11 | 3 | ||
12 | class Randomizer { | 4 | class Randomizer { |
13 | public: | 5 | public: |
14 | Randomizer(); | 6 | void Randomize(); |
15 | |||
16 | void Randomize(int seed); | ||
17 | |||
18 | void Randomize(std::vector<int>& panels, int flags); | ||
19 | void RandomizeRange(std::vector<int> &panels, int flags, size_t startIndex, size_t endIndex); | ||
20 | void SwapPanels(int panel1, int panel2, int flags); | ||
21 | void ReassignTargets(const std::vector<int>& panels, const std::vector<int>& order); | ||
22 | |||
23 | template <class T> | ||
24 | std::vector<T> ReadPanelData(int panel, int offset, size_t size) { | ||
25 | return _memory.ReadData<T>({GLOBALS, 0x18, panel*8, offset}, size); | ||
26 | } | ||
27 | |||
28 | template <class T> | ||
29 | void WritePanelData(int panel, int offset, const std::vector<T>& data) { | ||
30 | _memory.WriteData<T>({GLOBALS, 0x18, panel*8, offset}, data); | ||
31 | } | ||
32 | 7 | ||
33 | private: | 8 | private: |
34 | Memory _memory = Memory("witness64_d3d11.exe"); | 9 | RandomizerCore _core; |
10 | void RandomizeTutorial(); | ||
11 | void RandomizeSymmetry(); | ||
12 | void RandomizeDesert(); | ||
13 | void RandomizeQuarry(); | ||
14 | void RandomizeTreehouse(); | ||
15 | void RandomizeKeep(); | ||
16 | void RandomizeShadows(); | ||
17 | void RandomizeTown(); | ||
18 | void RandomizeMonastery(); | ||
19 | void RandomizeBunker(); | ||
20 | void RandomizeJungle(); | ||
21 | void RandomizeSwamp(); | ||
22 | void RandomizeMountain(); | ||
35 | }; | 23 | }; |
36 | |||
37 | #if GLOBALS == 0x5B28C0 | ||
38 | #define PATH_COLOR 0xC8 | ||
39 | #define REFLECTION_PATH_COLOR 0xD8 | ||
40 | #define DOT_COLOR 0xF8 | ||
41 | #define ACTIVE_COLOR 0x108 | ||
42 | #define BACKGROUND_REGION_COLOR 0x118 | ||
43 | #define SUCCESS_COLOR_A 0x128 | ||
44 | #define SUCCESS_COLOR_B 0x138 | ||
45 | #define STROBE_COLOR_A 0x148 | ||
46 | #define STROBE_COLOR_B 0x158 | ||
47 | #define ERROR_COLOR 0x168 | ||
48 | #define PATTERN_POINT_COLOR 0x188 | ||
49 | #define PATTERN_POINT_COLOR_A 0x198 | ||
50 | #define PATTERN_POINT_COLOR_B 0x1A8 | ||
51 | #define SYMBOL_A 0x1B8 | ||
52 | #define SYMBOL_B 0x1C8 | ||
53 | #define SYMBOL_C 0x1D8 | ||
54 | #define SYMBOL_D 0x1E8 | ||
55 | #define SYMBOL_E 0x1F8 | ||
56 | #define PUSH_SYMBOL_COLORS 0x208 | ||
57 | #define OUTER_BACKGROUND 0x20C | ||
58 | #define OUTER_BACKGROUND_MODE 0x21C | ||
59 | #define TRACED_EDGES 0x230 | ||
60 | #define AUDIO_PREFIX 0x278 | ||
61 | #define POWER 0x2A8 | ||
62 | #define TARGET 0x2BC | ||
63 | #define IS_CYLINDER 0x2FC | ||
64 | #define CYLINDER_Z0 0x300 | ||
65 | #define CYLINDER_Z1 0x304 | ||
66 | #define CYLINDER_RADIUS 0x308 | ||
67 | #define CURSOR_SPEED_SCALE 0x358 | ||
68 | #define SPECULAR_ADD 0x398 | ||
69 | #define SPECULAR_POWER 0x39C | ||
70 | #define PATH_WIDTH_SCALE 0x3A4 | ||
71 | #define STARTPOINT_SCALE 0x3A8 | ||
72 | #define NUM_DOTS 0x3B8 | ||
73 | #define NUM_CONNECTIONS 0x3BC | ||
74 | #define MAX_BROADCAST_DISTANCE 0x3C0 | ||
75 | #define DOT_POSITIONS 0x3C8 | ||
76 | #define DOT_FLAGS 0x3D0 | ||
77 | #define DOT_CONNECTION_A 0x3D8 | ||
78 | #define DOT_CONNECTION_B 0x3E0 | ||
79 | #define DECORATIONS 0x420 | ||
80 | #define DECORATION_FLAGS 0x428 | ||
81 | #define DECORATION_COLORS 0x430 | ||
82 | #define NUM_DECORATIONS 0x438 | ||
83 | #define REFLECTION_DATA 0x440 | ||
84 | #define GRID_SIZE_X 0x448 | ||
85 | #define GRID_SIZE_Y 0x44C | ||
86 | #define STYLE_FLAGS 0x450 | ||
87 | #define SEQUENCE_LEN 0x45C | ||
88 | #define SEQUENCE 0x460 | ||
89 | #define DOT_SEQUENCE_LEN 0x468 | ||
90 | #define DOT_SEQUENCE 0x470 | ||
91 | #define DOT_SEQUENCE_LEN_REFLECTION 0x478 | ||
92 | #define DOT_SEQUENCE_REFLECTION 0x480 | ||
93 | #define NUM_COLORED_REGIONS 0x4A0 | ||
94 | #define COLORED_REGIONS 0x4A8 | ||
95 | #define PANEL_TARGET 0x4B0 | ||
96 | #define SPECULAR_TEXTURE 0x4D8 | ||
97 | #define CABLE_TARGET_2 0xD8 | ||
98 | #elif GLOBALS == 0x62A080 | ||
99 | #define PATH_COLOR 0xC0 | ||
100 | #define REFLECTION_PATH_COLOR 0xD0 | ||
101 | #define DOT_COLOR 0xF0 | ||
102 | #define ACTIVE_COLOR 0x100 | ||
103 | #define BACKGROUND_REGION_COLOR 0x110 | ||
104 | #define SUCCESS_COLOR_A 0x120 | ||
105 | #define SUCCESS_COLOR_B 0x130 | ||
106 | #define STROBE_COLOR_A 0x140 | ||
107 | #define STROBE_COLOR_B 0x150 | ||
108 | #define ERROR_COLOR 0x160 | ||
109 | #define PATTERN_POINT_COLOR 0x180 | ||
110 | #define PATTERN_POINT_COLOR_A 0x190 | ||
111 | #define PATTERN_POINT_COLOR_B 0x1A0 | ||
112 | #define SYMBOL_A 0x1B0 | ||
113 | #define SYMBOL_B 0x1C0 | ||
114 | #define SYMBOL_C 0x1D0 | ||
115 | #define SYMBOL_D 0x1E0 | ||
116 | #define SYMBOL_E 0x1F0 | ||
117 | #define PUSH_SYMBOL_COLORS 0x200 | ||
118 | #define OUTER_BACKGROUND 0x204 | ||
119 | #define OUTER_BACKGROUND_MODE 0x214 | ||
120 | #define TRACED_EDGES 0x228 | ||
121 | #define AUDIO_PREFIX 0x270 | ||
122 | #define POWER 0x2A0 | ||
123 | #define TARGET 0x2B4 | ||
124 | #define IS_CYLINDER 0x2F4 | ||
125 | #define CYLINDER_Z0 0x2F8 | ||
126 | #define CYLINDER_Z1 0x2FC | ||
127 | #define CYLINDER_RADIUS 0x300 | ||
128 | #define CURSOR_SPEED_SCALE 0x350 | ||
129 | #define SPECULAR_ADD 0x38C | ||
130 | #define SPECULAR_POWER 0x390 | ||
131 | #define PATH_WIDTH_SCALE 0x39C | ||
132 | #define STARTPOINT_SCALE 0x3A0 | ||
133 | #define NUM_DOTS 0x3B4 | ||
134 | #define NUM_CONNECTIONS 0x3B8 | ||
135 | #define MAX_BROADCAST_DISTANCE 0x3BC | ||
136 | #define DOT_POSITIONS 0x3C0 | ||
137 | #define DOT_FLAGS 0x3C8 | ||
138 | #define DOT_CONNECTION_A 0x3D0 | ||
139 | #define DOT_CONNECTION_B 0x3D8 | ||
140 | #define DECORATIONS 0x418 | ||
141 | #define DECORATION_FLAGS 0x420 | ||
142 | #define DECORATION_COLORS 0x428 | ||
143 | #define NUM_DECORATIONS 0x430 | ||
144 | #define REFLECTION_DATA 0x438 | ||
145 | #define GRID_SIZE_X 0x440 | ||
146 | #define GRID_SIZE_Y 0x444 | ||
147 | #define STYLE_FLAGS 0x448 | ||
148 | #define SEQUENCE_LEN 0x454 | ||
149 | #define SEQUENCE 0x458 | ||
150 | #define DOT_SEQUENCE_LEN 0x460 | ||
151 | #define DOT_SEQUENCE 0x468 | ||
152 | #define DOT_SEQUENCE_LEN_REFLECTION 0x470 | ||
153 | #define DOT_SEQUENCE_REFLECTION 0x478 | ||
154 | #define NUM_COLORED_REGIONS 0x498 | ||
155 | #define COLORED_REGIONS 0x4A0 | ||
156 | #define PANEL_TARGET 0x4A8 | ||
157 | #define SPECULAR_TEXTURE 0x4D0 | ||
158 | #define CABLE_TARGET_2 0xD0 | ||
159 | #endif \ No newline at end of file | ||
diff --git a/Source/RandomizerCore.cpp b/Source/RandomizerCore.cpp new file mode 100644 index 0000000..ef0e6e6 --- /dev/null +++ b/Source/RandomizerCore.cpp | |||
@@ -0,0 +1,119 @@ | |||
1 | #include "RandomizerCore.h" | ||
2 | #include "Memory.h" | ||
3 | #include <sstream> | ||
4 | |||
5 | void RandomizerCore::Randomize(std::vector<int>& panels, int flags) { | ||
6 | return RandomizeRange(panels, flags, 0, panels.size()); | ||
7 | } | ||
8 | |||
9 | // Range is [start, end) | ||
10 | void RandomizerCore::RandomizeRange(std::vector<int> &panels, int flags, size_t startIndex, size_t endIndex) { | ||
11 | if (panels.size() == 0) return; | ||
12 | if (startIndex >= endIndex) return; | ||
13 | if (endIndex >= panels.size()) endIndex = panels.size(); | ||
14 | for (size_t i = endIndex-1; i > startIndex; i--) { | ||
15 | const size_t target = rand() % (i - startIndex) + startIndex; | ||
16 | if (i != target) { | ||
17 | // std::cout << "Swapping panels " << std::hex << panels[i] << " and " << std::hex << panels[target] << std::endl; | ||
18 | SwapPanels(panels[i], panels[target], flags); | ||
19 | std::swap(panels[i], panels[target]); // Panel indices in the array | ||
20 | } | ||
21 | } | ||
22 | } | ||
23 | |||
24 | void RandomizerCore::SwapPanels(int panel1, int panel2, int flags) { | ||
25 | std::map<int, int> offsets; | ||
26 | |||
27 | if (flags & SWAP_TARGETS) { | ||
28 | offsets[TARGET] = sizeof(int); | ||
29 | } | ||
30 | if (flags & SWAP_LINES) { | ||
31 | offsets[PATH_COLOR] = 16; | ||
32 | offsets[REFLECTION_PATH_COLOR] = 16; | ||
33 | offsets[DOT_COLOR] = 16; | ||
34 | offsets[ACTIVE_COLOR] = 16; | ||
35 | offsets[BACKGROUND_REGION_COLOR] = 16; | ||
36 | offsets[SUCCESS_COLOR_A] = 16; | ||
37 | offsets[SUCCESS_COLOR_B] = 16; | ||
38 | offsets[STROBE_COLOR_A] = 16; | ||
39 | offsets[STROBE_COLOR_B] = 16; | ||
40 | offsets[ERROR_COLOR] = 16; | ||
41 | offsets[PATTERN_POINT_COLOR] = 16; | ||
42 | offsets[PATTERN_POINT_COLOR_A] = 16; | ||
43 | offsets[PATTERN_POINT_COLOR_B] = 16; | ||
44 | offsets[SYMBOL_A] = 16; | ||
45 | offsets[SYMBOL_B] = 16; | ||
46 | offsets[SYMBOL_C] = 16; | ||
47 | offsets[SYMBOL_D] = 16; | ||
48 | offsets[SYMBOL_E] = 16; | ||
49 | offsets[PUSH_SYMBOL_COLORS] = sizeof(int); | ||
50 | offsets[OUTER_BACKGROUND] = 16; | ||
51 | offsets[OUTER_BACKGROUND_MODE] = sizeof(int); | ||
52 | offsets[TRACED_EDGES] = 16; | ||
53 | offsets[AUDIO_PREFIX] = sizeof(void*); | ||
54 | // offsets[IS_CYLINDER] = sizeof(int); | ||
55 | // offsets[CYLINDER_Z0] = sizeof(float); | ||
56 | // offsets[CYLINDER_Z1] = sizeof(float); | ||
57 | // offsets[CYLINDER_RADIUS] = sizeof(float); | ||
58 | offsets[SPECULAR_ADD] = sizeof(float); | ||
59 | offsets[SPECULAR_POWER] = sizeof(int); | ||
60 | offsets[PATH_WIDTH_SCALE] = sizeof(float); | ||
61 | offsets[STARTPOINT_SCALE] = sizeof(float); | ||
62 | offsets[NUM_DOTS] = sizeof(int); | ||
63 | offsets[NUM_CONNECTIONS] = sizeof(int); | ||
64 | offsets[DOT_POSITIONS] = sizeof(void*); | ||
65 | offsets[DOT_FLAGS] = sizeof(void*); | ||
66 | offsets[DOT_CONNECTION_A] = sizeof(void*); | ||
67 | offsets[DOT_CONNECTION_B] = sizeof(void*); | ||
68 | offsets[DECORATIONS] = sizeof(void*); | ||
69 | offsets[DECORATION_FLAGS] = sizeof(void*); | ||
70 | offsets[DECORATION_COLORS] = sizeof(void*); | ||
71 | offsets[NUM_DECORATIONS] = sizeof(int); | ||
72 | offsets[REFLECTION_DATA] = sizeof(void*); | ||
73 | offsets[GRID_SIZE_X] = sizeof(int); | ||
74 | offsets[GRID_SIZE_Y] = sizeof(int); | ||
75 | offsets[STYLE_FLAGS] = sizeof(int); | ||
76 | offsets[SEQUENCE_LEN] = sizeof(int); | ||
77 | offsets[SEQUENCE] = sizeof(void*); | ||
78 | offsets[DOT_SEQUENCE_LEN] = sizeof(int); | ||
79 | offsets[DOT_SEQUENCE] = sizeof(void*); | ||
80 | offsets[DOT_SEQUENCE_LEN_REFLECTION] = sizeof(int); | ||
81 | offsets[DOT_SEQUENCE_REFLECTION] = sizeof(void*); | ||
82 | offsets[NUM_COLORED_REGIONS] = sizeof(int); | ||
83 | offsets[COLORED_REGIONS] = sizeof(void*); | ||
84 | offsets[PANEL_TARGET] = sizeof(void*); | ||
85 | offsets[SPECULAR_TEXTURE] = sizeof(void*); | ||
86 | } | ||
87 | |||
88 | for (auto const& [offset, size] : offsets) { | ||
89 | std::vector<byte> panel1data = ReadPanelData<byte>(panel1, offset, size); | ||
90 | std::vector<byte> panel2data = ReadPanelData<byte>(panel2, offset, size); | ||
91 | WritePanelData<byte>(panel2, offset, panel1data); | ||
92 | WritePanelData<byte>(panel1, offset, panel2data); | ||
93 | } | ||
94 | } | ||
95 | |||
96 | void RandomizerCore::ReassignTargets(const std::vector<int>& panels, const std::vector<int>& order) { | ||
97 | // This list is offset by 1, so the target of the Nth panel is in position N (aka the N+1th element) | ||
98 | // The first panel may not have a wire to power it, so we use the panel ID itself. | ||
99 | std::vector<int> targetToActivatePanel = {panels[0] + 1}; | ||
100 | for (const int panel : panels) { | ||
101 | int target = ReadPanelData<int>(panel, TARGET, 1)[0]; | ||
102 | targetToActivatePanel.push_back(target); | ||
103 | } | ||
104 | |||
105 | for (size_t i=0; i<order.size() - 1; i++) { | ||
106 | // Set the target of order[i] to order[i+1], using the "real" target as determined above. | ||
107 | const int panelTarget = targetToActivatePanel[order[i+1]]; | ||
108 | |||
109 | std::stringstream message; | ||
110 | message << "i=" << i; | ||
111 | message << " order[i]=" << order[i]; | ||
112 | message << " order[i+1]=" << order[i+1]; | ||
113 | message << " panels[order[i]]=0x" << std::hex << panels[order[i]]; | ||
114 | message << " panels[order[i+1]]=0x" << std::hex << panels[order[i+1]]; | ||
115 | message << " panelTarget=0x" << std::hex << panelTarget << std::endl; | ||
116 | OutputDebugStringA(message.str().c_str()); | ||
117 | WritePanelData<int>(panels[order[i]], TARGET, {panelTarget}); | ||
118 | } | ||
119 | } | ||
diff --git a/Source/RandomizerCore.h b/Source/RandomizerCore.h new file mode 100644 index 0000000..4002611 --- /dev/null +++ b/Source/RandomizerCore.h | |||
@@ -0,0 +1,155 @@ | |||
1 | #pragma once | ||
2 | #include "Memory.h" | ||
3 | |||
4 | // #define GLOBALS 0x5B28C0 | ||
5 | #define GLOBALS 0x62A080 | ||
6 | |||
7 | __declspec(selectany) int SWAP_NONE = 0x0; | ||
8 | __declspec(selectany) int SWAP_TARGETS = 0x1; | ||
9 | __declspec(selectany) int SWAP_LINES = 0x2; | ||
10 | |||
11 | class RandomizerCore | ||
12 | { | ||
13 | public: | ||
14 | void Randomize(std::vector<int>& panels, int flags); | ||
15 | void RandomizeRange(std::vector<int> &panels, int flags, size_t startIndex, size_t endIndex); | ||
16 | void SwapPanels(int panel1, int panel2, int flags); | ||
17 | void ReassignTargets(const std::vector<int>& panels, const std::vector<int>& order); | ||
18 | |||
19 | template <class T> | ||
20 | std::vector<T> ReadPanelData(int panel, int offset, size_t size) { | ||
21 | return _memory.ReadData<T>({GLOBALS, 0x18, panel*8, offset}, size); | ||
22 | } | ||
23 | |||
24 | template <class T> | ||
25 | void WritePanelData(int panel, int offset, const std::vector<T>& data) { | ||
26 | _memory.WriteData<T>({GLOBALS, 0x18, panel*8, offset}, data); | ||
27 | } | ||
28 | |||
29 | private: | ||
30 | Memory _memory = Memory("witness64_d3d11.exe"); | ||
31 | }; | ||
32 | |||
33 | #if GLOBALS == 0x5B28C0 | ||
34 | #define PATH_COLOR 0xC8 | ||
35 | #define REFLECTION_PATH_COLOR 0xD8 | ||
36 | #define DOT_COLOR 0xF8 | ||
37 | #define ACTIVE_COLOR 0x108 | ||
38 | #define BACKGROUND_REGION_COLOR 0x118 | ||
39 | #define SUCCESS_COLOR_A 0x128 | ||
40 | #define SUCCESS_COLOR_B 0x138 | ||
41 | #define STROBE_COLOR_A 0x148 | ||
42 | #define STROBE_COLOR_B 0x158 | ||
43 | #define ERROR_COLOR 0x168 | ||
44 | #define PATTERN_POINT_COLOR 0x188 | ||
45 | #define PATTERN_POINT_COLOR_A 0x198 | ||
46 | #define PATTERN_POINT_COLOR_B 0x1A8 | ||
47 | #define SYMBOL_A 0x1B8 | ||
48 | #define SYMBOL_B 0x1C8 | ||
49 | #define SYMBOL_C 0x1D8 | ||
50 | #define SYMBOL_D 0x1E8 | ||
51 | #define SYMBOL_E 0x1F8 | ||
52 | #define PUSH_SYMBOL_COLORS 0x208 | ||
53 | #define OUTER_BACKGROUND 0x20C | ||
54 | #define OUTER_BACKGROUND_MODE 0x21C | ||
55 | #define TRACED_EDGES 0x230 | ||
56 | #define AUDIO_PREFIX 0x278 | ||
57 | #define POWER 0x2A8 | ||
58 | #define TARGET 0x2BC | ||
59 | #define IS_CYLINDER 0x2FC | ||
60 | #define CYLINDER_Z0 0x300 | ||
61 | #define CYLINDER_Z1 0x304 | ||
62 | #define CYLINDER_RADIUS 0x308 | ||
63 | #define CURSOR_SPEED_SCALE 0x358 | ||
64 | #define SPECULAR_ADD 0x398 | ||
65 | #define SPECULAR_POWER 0x39C | ||
66 | #define PATH_WIDTH_SCALE 0x3A4 | ||
67 | #define STARTPOINT_SCALE 0x3A8 | ||
68 | #define NUM_DOTS 0x3B8 | ||
69 | #define NUM_CONNECTIONS 0x3BC | ||
70 | #define MAX_BROADCAST_DISTANCE 0x3C0 | ||
71 | #define DOT_POSITIONS 0x3C8 | ||
72 | #define DOT_FLAGS 0x3D0 | ||
73 | #define DOT_CONNECTION_A 0x3D8 | ||
74 | #define DOT_CONNECTION_B 0x3E0 | ||
75 | #define DECORATIONS 0x420 | ||
76 | #define DECORATION_FLAGS 0x428 | ||
77 | #define DECORATION_COLORS 0x430 | ||
78 | #define NUM_DECORATIONS 0x438 | ||
79 | #define REFLECTION_DATA 0x440 | ||
80 | #define GRID_SIZE_X 0x448 | ||
81 | #define GRID_SIZE_Y 0x44C | ||
82 | #define STYLE_FLAGS 0x450 | ||
83 | #define SEQUENCE_LEN 0x45C | ||
84 | #define SEQUENCE 0x460 | ||
85 | #define DOT_SEQUENCE_LEN 0x468 | ||
86 | #define DOT_SEQUENCE 0x470 | ||
87 | #define DOT_SEQUENCE_LEN_REFLECTION 0x478 | ||
88 | #define DOT_SEQUENCE_REFLECTION 0x480 | ||
89 | #define NUM_COLORED_REGIONS 0x4A0 | ||
90 | #define COLORED_REGIONS 0x4A8 | ||
91 | #define PANEL_TARGET 0x4B0 | ||
92 | #define SPECULAR_TEXTURE 0x4D8 | ||
93 | #define CABLE_TARGET_2 0xD8 | ||
94 | #elif GLOBALS == 0x62A080 | ||
95 | #define PATH_COLOR 0xC0 | ||
96 | #define REFLECTION_PATH_COLOR 0xD0 | ||
97 | #define DOT_COLOR 0xF0 | ||
98 | #define ACTIVE_COLOR 0x100 | ||
99 | #define BACKGROUND_REGION_COLOR 0x110 | ||
100 | #define SUCCESS_COLOR_A 0x120 | ||
101 | #define SUCCESS_COLOR_B 0x130 | ||
102 | #define STROBE_COLOR_A 0x140 | ||
103 | #define STROBE_COLOR_B 0x150 | ||
104 | #define ERROR_COLOR 0x160 | ||
105 | #define PATTERN_POINT_COLOR 0x180 | ||
106 | #define PATTERN_POINT_COLOR_A 0x190 | ||
107 | #define PATTERN_POINT_COLOR_B 0x1A0 | ||
108 | #define SYMBOL_A 0x1B0 | ||
109 | #define SYMBOL_B 0x1C0 | ||
110 | #define SYMBOL_C 0x1D0 | ||
111 | #define SYMBOL_D 0x1E0 | ||
112 | #define SYMBOL_E 0x1F0 | ||
113 | #define PUSH_SYMBOL_COLORS 0x200 | ||
114 | #define OUTER_BACKGROUND 0x204 | ||
115 | #define OUTER_BACKGROUND_MODE 0x214 | ||
116 | #define TRACED_EDGES 0x228 | ||
117 | #define AUDIO_PREFIX 0x270 | ||
118 | #define POWER 0x2A0 | ||
119 | #define TARGET 0x2B4 | ||
120 | #define IS_CYLINDER 0x2F4 | ||
121 | #define CYLINDER_Z0 0x2F8 | ||
122 | #define CYLINDER_Z1 0x2FC | ||
123 | #define CYLINDER_RADIUS 0x300 | ||
124 | #define CURSOR_SPEED_SCALE 0x350 | ||
125 | #define SPECULAR_ADD 0x38C | ||
126 | #define SPECULAR_POWER 0x390 | ||
127 | #define PATH_WIDTH_SCALE 0x39C | ||
128 | #define STARTPOINT_SCALE 0x3A0 | ||
129 | #define NUM_DOTS 0x3B4 | ||
130 | #define NUM_CONNECTIONS 0x3B8 | ||
131 | #define MAX_BROADCAST_DISTANCE 0x3BC | ||
132 | #define DOT_POSITIONS 0x3C0 | ||
133 | #define DOT_FLAGS 0x3C8 | ||
134 | #define DOT_CONNECTION_A 0x3D0 | ||
135 | #define DOT_CONNECTION_B 0x3D8 | ||
136 | #define DECORATIONS 0x418 | ||
137 | #define DECORATION_FLAGS 0x420 | ||
138 | #define DECORATION_COLORS 0x428 | ||
139 | #define NUM_DECORATIONS 0x430 | ||
140 | #define REFLECTION_DATA 0x438 | ||
141 | #define GRID_SIZE_X 0x440 | ||
142 | #define GRID_SIZE_Y 0x444 | ||
143 | #define STYLE_FLAGS 0x448 | ||
144 | #define SEQUENCE_LEN 0x454 | ||
145 | #define SEQUENCE 0x458 | ||
146 | #define DOT_SEQUENCE_LEN 0x460 | ||
147 | #define DOT_SEQUENCE 0x468 | ||
148 | #define DOT_SEQUENCE_LEN_REFLECTION 0x470 | ||
149 | #define DOT_SEQUENCE_REFLECTION 0x478 | ||
150 | #define NUM_COLORED_REGIONS 0x498 | ||
151 | #define COLORED_REGIONS 0x4A0 | ||
152 | #define PANEL_TARGET 0x4A8 | ||
153 | #define SPECULAR_TEXTURE 0x4D0 | ||
154 | #define CABLE_TARGET_2 0xD0 | ||
155 | #endif \ No newline at end of file | ||