· 5 years ago · May 26, 2020, 07:00 PM
1// Create Math.seedrandom function and maybe some other stuff idk can't be bothered to understand this obfuscated crap
2(function(j, i, g, m, k, n, o) {
3 function q(b) {
4 var e, f, a = this,
5 c = b.length,
6 d = 0,
7 h = a.i = a.j = a.m = 0;
8 a.S = [];
9 a.c = [];
10 for (c || (b = [c++]); d < g;) a.S[d] = d++;
11 for (d = 0; d < g; d++) e = a.S[d], h = h + e + b[d % c] & g - 1, f = a.S[h], a.S[d] = f, a.S[h] = e;
12 a.g = function(b) {
13 var c = a.S,
14 d = a.i + 1 & g - 1,
15 e = c[d],
16 f = a.j + e & g - 1,
17 h = c[f];
18 c[d] = h;
19 c[f] = e;
20 for (var i = c[e + h & g - 1]; --b;) d = d + 1 & g - 1, e = c[d], f = f + e & g - 1, h = c[f], c[d] = h, c[f] = e, i = i * g + c[e + h & g - 1];
21 a.i = d;
22 a.j = f;
23 return i
24 };
25 a.g(g)
26 }
27
28 function p(b, e, f, a, c) {
29 f = [];
30 c = typeof b;
31 if (e && c == "object")
32 for (a in b)
33 if (a.indexOf("S") < 5) try {
34 f.push(p(b[a], e - 1))
35 } catch (d) {}
36 return f.length ? f : b + (c != "string" ? "\0" : "")
37 }
38
39 function l(b, e, f, a) {
40 b += "";
41 for (a = f = 0; a < b.length; a++) {
42 var c = e,
43 d = a & g - 1,
44 h = (f ^= e[a & g - 1] * 19) + b.charCodeAt(a);
45 c[d] = h & g - 1
46 }
47 b = "";
48 for (a in e) b += String.fromCharCode(e[a]);
49 return b
50 }
51 i.seedrandom = function(b, e) {
52 var f = [],
53 a;
54 b = l(p(e ? [b, j] : arguments.length ? b : [(new Date).getTime(), j, window], 3), f);
55 a = new q(f);
56 l(a.S, j);
57 i.random = function() {
58 for (var c = a.g(m), d = o, b = 0; c < k;) c = (c + b) * g, d *= g, b = a.g(1);
59 for (; c >= n;) c /= 2, d /= 2, b >>>= 1;
60 return (c + b) / d
61 };
62 return b
63 };
64 o = i.pow(g, m);
65 k = i.pow(2, k);
66 n = k * 2;
67 l(i.random(), j)
68})([], Math, 256, 6, 52);
69
70//Create a magic square that the board will be based on
71function magicSquare() {
72 var A = B = C = D = E = f = g = h = i = j = 0;
73 //var tableA = [A, B, C, D, E];
74 //var tableF = [f, g, h, i, j];
75 //this whole thing generates one of the 144 "unique" 5x5 magic squares
76 //for more info visit https://www.grogono.com/magic/5x5pan144.php
77 var table1 = [];
78 table1[0] = [0, 5, 10, 15, 20];
79 table1[1] = [0, 5, 10, 20, 15];
80 table1[2] = [0, 5, 15, 10, 20];
81 table1[3] = [0, 5, 15, 20, 10];
82 table1[4] = [0, 5, 20, 10, 15];
83 table1[5] = [0, 5, 20, 15, 10];
84
85 var table2 = [];
86 table2[0] = [0, 1, 2, 3, 4];
87 table2[1] = [0, 1, 2, 4, 3];
88 table2[2] = [0, 1, 3, 2, 4];
89 table2[3] = [0, 1, 3, 4, 2];
90 table2[4] = [0, 1, 4, 2, 3];
91 table2[5] = [0, 1, 4, 3, 2];
92 table2[6] = [0, 2, 1, 3, 4];
93 table2[7] = [0, 2, 1, 4, 3];
94 table2[8] = [0, 2, 3, 1, 4];
95 table2[9] = [0, 2, 3, 4, 1];
96 table2[10] = [0, 2, 4, 1, 3];
97 table2[11] = [0, 2, 4, 3, 1];
98 table2[12] = [0, 3, 1, 2, 4];
99 table2[13] = [0, 3, 1, 4, 2];
100 table2[14] = [0, 3, 2, 1, 4];
101 table2[15] = [0, 3, 2, 4, 1];
102 table2[16] = [0, 3, 4, 1, 2];
103 table2[17] = [0, 3, 4, 2, 1];
104 table2[18] = [0, 4, 1, 2, 3];
105 table2[19] = [0, 4, 1, 3, 2];
106 table2[20] = [0, 4, 2, 1, 3];
107 table2[21] = [0, 4, 2, 3, 1];
108 table2[22] = [0, 4, 3, 1, 2];
109 table2[23] = [0, 4, 3, 2, 1];
110
111 var randTable1 = table1[Math.floor(6 * Math.random())];
112 var randTable2 = table2[Math.floor(24 * Math.random())];
113 /*for (var x = 0; x <= 4; x++) {
114 tableA[x] = randTable1[x];
115 }
116 for (var y = 0; y <= 4; y++) {
117 tableF[y] = randTable2[y];
118 }*/
119 A = randTable1[0];
120 B = randTable1[1];
121 C = randTable1[2];
122 D = randTable1[3];
123 E = randTable1[4];
124 f = randTable2[0];
125 g = randTable2[1];
126 h = randTable2[2];
127 i = randTable2[3];
128 j = randTable2[4];
129
130 var template = [];
131 template[0] = [(A+f+1), (B+i+1), (C+g+1), (D+j+1), (E+h+1)];
132 template[1] = [(D+g+1), (E+j+1), (A+h+1), (B+f+1), (C+i+1)];
133 template[2] = [(B+h+1), (C+f+1), (D+i+1), (E+g+1), (A+j+1)];
134 template[3] = [(E+i+1), (A+g+1), (B+j+1), (C+h+1), (D+f+1)];
135 template[4] = [(C+j+1), (D+h+1), (E+f+1), (A+i+1), (B+g+1)];
136
137 //here starts the translocations, rotations, and reflections that increase the possible magic squares to 28800
138 var ro = Math.floor(4 * Math.random());
139 var rf = Math.floor(2 * Math.random());
140 var tH = Math.floor(5 * Math.random());
141 var tV = Math.floor(5 * Math.random());
142
143 template = translocate(template, tH, 0);
144 template = translocate(template, tV, 1);
145 template = rotate(template, ro);
146 if (rf == 1) {
147 template.reverse();
148 }
149
150 function inverse(t) { //inverts the table
151 var s = [];
152 for (var j = 0; j < t.length; j++) {
153 s.push([]);
154 }
155 for (var j = 0; j < t.length; j++) {
156 for (var k = 0; k < t.length; k++) {
157 s[j][k] = t[k][j];
158 }
159 }
160 }
161
162 function rotate(t, i) { //rotates ccw i times
163 for (var j = 1; j <= i; j++) {
164 inverse(t);
165 t.reverse();
166 }
167 return t;
168 }
169
170 function translocate(t, i, dir) {
171 if (dir == 1) { //shifts down i times
172 for (j = 1; j <= i; j++) {
173 var s = t.shift();
174 t.push(s);
175 }
176 } else {
177 for (j = 1; j <= i; j++) { //shifts left i times
178 for (k = 0; k <= 4; k++) {
179 var s = t[k].shift();
180 t[k].push(s);
181 }
182 }
183 }
184 return t;
185 }
186 //do a checksum to make sure it's a valid magic square
187 /*try {
188 var checksumTotal = 0
189 for (var x = 0; x <= 4; x++) {
190 var checksumLine = 0;
191 for (var y = 0; y <= 4; y++) {
192 checksumTotal += template[x][y];
193 checksumLine += template[x][y];
194 }
195 if (checksumLine != 65) {
196 throw "Line sum is not 65";
197 }
198 }
199 if (checksumTotal != 325) {
200 throw "Sum is not 325";
201 }
202 }
203 catch(err) {
204 console.log(err);
205 }*/
206
207 return template;
208}
209
210//imports an SRLv5 generator if one is provided instead of the used format
211function importSRLv5(importList) {
212 var bingoList = { };
213 var bingoTypes = { };
214 for (i = 0; i < importList.length; i++) {
215 var Diff = i + 1;
216 for (var goal of importList[i]) {
217 //a lot of redundant code here but I don't feel like changing it; if anything this function could be its own script
218 goal.diff = Diff;
219 if (!goal.hasOwnProperty("excludes")) {goal.excludes = [];}
220 if (!goal.hasOwnProperty("synergy")) {goal.synergy = [];}
221 //console.log(goal);
222
223 bingoList = Object.defineProperty(bingoList, goal.name, {
224 value: {
225 "Desc": goal.name,
226 "Diff": goal.diff,
227 "Types": goal.types,
228 "Excludes": goal.excludes,
229 "Synergy": goal.synergy
230 },
231 writable: true,
232 configurable: true,
233 enumerable: true
234 });
235
236 for (var type of goal.types) {
237 if (!bingoTypes.hasOwnProperty(type)) {
238 bingoTypes = Object.defineProperty(bingoTypes, type, {
239 value: {"Max": 5},
240 writable: true,
241 configurable: true,
242 enumerable: true
243 });
244 }
245 }
246 }
247 }
248 return [bingoList, bingoTypes];
249}
250
251//Reduces fluff in bingoList object if there's a method to set defaults
252function preprocessBingoList(bingoList) {
253 for (const key of Object.keys(bingoList)) {
254 bingoList[key].name = key;
255
256 if (!bingoList[key].hasOwnProperty("Desc")) {
257 bingoList[key].Desc = key;
258 }
259
260 if (!bingoList[key].hasOwnProperty("Diff")) {
261 bingoList[key].Diff = 0;
262 }
263
264 if (!bingoList[key].hasOwnProperty("Types")) {
265 bingoList[key].Types = [];
266 }
267
268 if (!bingoList[key].hasOwnProperty("Excludes")) {
269 bingoList[key].Excludes = [];
270 }
271
272 if (!bingoList[key].hasOwnProperty("Synergy")) {
273 bingoList[key].Synergy = [];
274 }
275 }
276}
277
278//synerGen: a bingo generator based on SRLv5 and Hollow Knight's generators.
279bingoGenerator = function(bingoList, opts) {
280 //Import the provided SRLv5 generator if one exists. DISCLAIMER: THIS REPLACES THE ORIGINAL BINGOLIST. MAKE SURE TO ONLY USE ONE FORMAT.
281 if (importList != []) {
282 arr = importSRLv5(importList);
283 bingoList = arr[0];
284 bingoTypes = arr[1];
285 //console.log(bingoList);
286 }
287
288 //Make sure everything exists that should
289 preprocessBingoList(bingoList);
290
291 //Separate goals into currently choosable / unchoosable (all goals are choosable at the start)
292 var choosable = [];
293 var unchoosable = [];
294 for (const key of Object.keys(bingoList)) {
295 choosable.push(key);
296 }
297 //console.log("Total goals: " + choosable.length);
298
299 //Create counts for all types
300 var types = { };
301 for (const key of Object.keys(bingoTypes)) {
302 if (!bingoTypes[key].hasOwnProperty("Max")) {
303 bingoTypes.key.Max = 5;
304 }
305 types[key] = bingoTypes[key].Max;
306 }
307 //console.log("Total types: " + types.length);
308
309
310 //Seed the random
311 seed = Math.seedrandom(opts.seed || Math.ceil(999999 * Math.random()));
312 //console.log("Seed: " + seed);
313
314 //create a 1-dimensional array from the 2-dimensional matrix magicSquare[][]
315 var square = magicSquare();
316 var bingoBoard = square[0].concat(square[1], square[2], square[3], square[4]);
317
318 var unchosenDiffs = bingoBoard.slice();
319 var chosenGoals = [];
320 for (var i = 1; i <= 25; i++) {
321 chosenGoals.push("");
322 }
323
324 for (var i = 1; i <= 25; i++) {
325 //this is necessary on the edge case that all the exclusions and difficulties wind up eliminating every goal
326 if (choosable.length == 0) {
327 //console.log("\nchoosable is empty, current unchoosable goals: " + unchoosable.length);
328 var newChoosableDiffs = [];
329 //add all goals with difficulty one more or less than any of the remaining difficulties back into choosable[]
330 for (var j of unchosenDiffs) {
331 var plusOne = j + 1;
332 var minusOne = j - 1;
333 if (!newChoosableDiffs.includes(plusOne) && plusOne <= 25) {
334 newChoosableDiffs.push(plusOne);
335 }
336 if (!newChoosableDiffs.includes(minusOne) && minusOne >= 1) {
337 newChoosableDiffs.push(minusOne);
338 }
339 }
340 for (var k = 0; k < unchoosable.length; k++) {
341 if (newChoosableDiffs.includes(bingoList[unchoosable[k]].Diff)) {
342 choosable = choosable.concat(unchoosable.splice(k, 1));
343 k--;
344 }
345 }
346 //if choosable[] is still empty, just move everything from unchoosable[] back
347 if (choosable.length == 0) {
348 choosable = unchoosable;
349 unchoosable = [];
350 }
351 }
352
353 //finally, choosing goals can begin
354 //Get a random goal, add to chosen
355 var index = Math.floor(Math.random() * choosable.length);
356 var goal = bingoList[choosable[index]];
357 var diff = goal.Diff;
358 var diffIndex = 0;
359 if (goal.Diff == 0) {
360 diffIndex = chosenGoals.indexOf("");
361 } else {
362 diffIndex = bingoBoard.indexOf(diff);
363 //deal with the edge case of the difficulty not matching
364 if (chosenGoals[diffIndex] != "") {
365 diffIndex = bingoBoard.indexOf(diff + 1);
366 if (chosenGoals[diffIndex] != "") {
367 diffIndex = bingoBoard.indexOf(diff - 1);
368 if (chosenGoals[diffIndex] != "") {
369 diffIndex = chosenGoals.indexOf("");
370 }
371 }
372 }
373 }
374 chosenGoals[diffIndex] = { "name": goal.Desc };
375 //console.log("Goal " + i + " chosen: " + goal.name + "; difficulty: " + goal.Diff);
376
377 //remove the chosen goal and any duplicates of it completely
378 for (var j = 0; j < choosable.length; j++) {
379 if (choosable[j] == goal.name) {
380 choosable.splice(j, 1);
381 }
382 }
383 //remove the goal's difficulty from unchosenDiffs[]
384 var unchosenDiffIndex = unchosenDiffs.indexOf(goal.Diff);
385 if (goal.Diff == 0) {
386 unchosenDiffIndex = bingoBoard.indexOf(diffIndex);
387 }
388 if (unchosenDiffIndex != -1) {
389 unchosenDiffs.splice(unchosenDiffIndex, 1);
390 }
391
392 //console.log(goal);
393
394 //increment type counters if relevant, also remove other goals of the same type if relevant
395 for (var j = 0; j < goal.Types.length; j++) {
396 types[goal.Types[j]]--;
397 if (types[goal.Types] <= 0) {
398 for (var k = 0; k < choosable.length; k++) {
399 for (var l = 0; l < bingoList[choosable[k]].Types.length; l++) {
400 if (bingoList[choosable[k]].Types[l] === goal.Types[j]) {
401 unchoosable = unchoosable.concat(choosable.splice(k, 1));
402 k--;
403 }
404 }
405 }
406 }
407 }
408
409 //remove all goals of the same difficulty from choosable[], also remove excluded goals if relevant
410 for (var j = 0; j < choosable.length; j++) {
411 if (bingoList[choosable[j]].Diff == goal.Diff && goal.Diff != 0) {
412 unchoosable = unchoosable.concat(choosable.splice(j, 1));
413 j--;
414 continue;
415 }
416 for (var k = 0; k < goal.Excludes.length; k++) {
417 if (choosable[j] == goal.Excludes[k]) {
418 unchoosable = unchoosable.concat(choosable.splice(j, 1));
419 j--;
420 }
421 }
422 }
423 //console.log("Current unchoosable goals: " + unchoosable.length);
424 //duplicate all goals sharing synergies with the chosen goal in choosable[] to make them more likely to be chosen
425 for (var j = 0; j < goal.Synergy.length; j++) {
426 var temp = [];
427 for (var k = 0; k < choosable.length; k++) {
428 if (goal.Synergy[j] == choosable[k]) { //check if the goal itself is a synergy
429 temp.push(choosable[k]);
430 }
431 for (var l = 0; l < bingoList[choosable[k]].Synergy.length; l++) { //check if it shares a synergy group that isn't an existing goal
432 if (goal.Synergy[j] == bingoList[choosable[k]].Synergy[l]
433 && !choosable.includes(bingoList[choosable[k]].Synergy[l])
434 && !unchoosable.includes(bingoList[choosable[k]].Synergy[l])) {
435 temp.push(choosable[k]);
436 }
437 }
438 }
439 choosable = choosable.concat(temp);
440 }
441 }
442 return chosenGoals;
443}
444
445
446
447var bingoList = { };
448var bingoTypes = { };
449var importList = [[
450 { "name": "Talk to Theo in Crossing", "types": ["earlygame","cutscene"] },
451 { "name": "Complete 1A Start without jumping", "types": ["earlygame","task"] },
452 { "name": "All Berries in Start of 1A (6)", "types": ["checkpoint_berries"] },
453 { "name": "All Berries in Chasm (5)", "types": ["checkpoint_berries"] },
454 { "name": "Get a 1-Up in 1A", "types": ["1up","earlygame"] },
455 { "name": "Forsaken City Blue Heart", "types": ["hearts","earlygame"] },
456 { "name": "Complete Chasm without dashing", "types": ["earlygame","task"] },
457 { "name": "Complete 1A Start without dashing", "types": ["earlygame","task"] },
458 { "name": "Forsaken City Cassette", "types": ["1b","earlygame"] },
459 { "name": "Old Site Blue Heart", "types": ["hearts","earlygame"] }
460],[
461 { "name": "Get two 1-Ups", "types": ["1up"] },
462 { "name": "10 Berries in 1A", "types": ["amount_berries"] },
463 { "name": "Talk to Theo in Awake", "types": ["earlygame","awake"] },
464 { "name": "Take hidden path before Cliff Face", "types": ["task","midgame"] },
465 { "name": "All Berries in Awake (1)", "types": ["checkpoint_berries"] },
466 { "name": "All Berries in Intervention (8)", "types": ["checkpoint_berries"] },
467 { "name": "Complete Awake without jumping", "types": ["earlygame","awake"] },
468 { "name": "Complete Awake without dashing", "types": ["earlygame","awake"] },
469 { "name": "All Berries in Start of 2A (9)", "types": ["checkpoint_berries"] },
470 { "name": "2 Hearts", "types": ["amount_hearts"] }
471],[
472 { "name": "5 Berries in 3 Chapters", "types": ["amount_berries"] },
473 { "name": "Complete 1 B-Side", "types": ["amount_chapters"] },
474 { "name": "Read the Poem in 2A", "types": ["earlygame","awake"] },
475 { "name": "Talk to Theo in Elevator Shaft", "types": ["resort_cutscene","cutscene"] },
476 { "name": "Complete Intervention without jumping", "types": ["earlygame","task"] },
477 { "name": "All Berries in Crossing (9)", "types": ["checkpoint_berries"] },
478 { "name": "10 Berries in 2A", "types": ["amount_berries"] },
479 { "name": "Find Letter and PICO-8 in Huge Mess", "types": ["resort_cutscene","cutscene"] },
480 { "name": "Get a 1-Up in 2 Chapters", "types": ["1up","challenge"] },
481 { "name": "Grabless Start of 3A", "types": ["grabless"] }
482],[
483 { "name": "Get a 1-Up in 2A", "types": ["1up"] },
484 { "name": "Reach Old Site in PICO-8", "types": ["pico-8"] },
485 { "name": "Forsaken City B-Side", "types": ["1b"] },
486 { "name": "All Collectibles in 1A", "types": ["amount_berries"] },
487 { "name": "Complete Crossing without dashing", "types": ["challenge","task"] },
488 { "name": "Old Site Cassette", "types": ["2b","earlygame"] },
489 { "name": "Complete Shrine without dashing", "types": ["task","midgame"] },
490 { "name": "Grabless Start of 4A", "types": ["grabless","midgame"] },
491 { "name": "Get a 1-Up in 4A", "types": ["1up","challenge","midgame"] },
492 { "name": "2 Cassettes", "types": ["amount_cassettes"] },
493 { "name": "Get 2 Keys", "types": ["keys"] },
494 { "name": "Get 3 Keys", "types": ["keys"] }
495],[
496 { "name": "20 Berries", "types": ["amount_berries"] },
497 { "name": "Get 5 Berries in PICO-8", "types": ["pico-8"] },
498 { "name": "Old Site B-Side", "types": ["2b"] },
499 { "name": "Grabless 1A", "types": ["grabless"] },
500 { "name": "Grabless 2A", "types": ["grabless"] },
501 { "name": "Get three 1-Ups", "types": ["1up","challenge"] },
502 { "name": "Get a 1-Up in 5A", "types": ["1up","challenge"] },
503 { "name": "All Berries in Elevator Shaft (4)", "types": ["checkpoint_berries"] },
504 { "name": "Celestial Resort Blue Heart", "types": ["hearts"] },
505 { "name": "Hit a Kevin block from all 4 sides", "types": ["task"] }
506],[
507 { "name": "All Berries in Huge Mess (7)", "types": ["checkpoint_berries"] },
508 { "name": "Use 3 Binoculars in B-Sides", "types": ["binoculars","earlygame"] },
509 { "name": "Blue and Red Heart in Forsaken City", "types": ["1b"] },
510 { "name": "Blue and Red Heart in Old Site", "types": ["2b"] },
511 { "name": "All Collectibles in 2A", "types": ["amount_berries"] },
512 { "name": "Grabless Huge Mess", "types": ["grabless"] },
513 { "name": "Mirror Temple Cassette", "types": ["5b","midgame"] },
514 { "name": "5 Berries in 4 Chapters", "types": ["amount_berries"] },
515 { "name": "Huge Mess: Chest -> Books -> Towel", "types": ["huge_mess_pathing"] },
516 { "name": "Huge Mess: Chest -> Towel -> Books", "types": ["huge_mess_pathing"] }
517],[
518 { "name": "2 Hearts and 2 Cassettes", "types": ["amount_hearts","amount_cassettes"] },
519 { "name": "1 Blue and 1 Red Heart", "types": ["amount_hearts","amount_chapters"] },
520 { "name": "2 optional Theo Cutscenes", "types": ["cutscene"] },
521 { "name": "Get a 1-Up in 3 Chapters", "types": ["1up","challenge"] },
522 { "name": "Read Diary in Elevator Shaft", "types": ["resort_cutscene","cutscene"] },
523 { "name": "Grabless Elevator Shaft", "types": ["grabless"] },
524 { "name": "All Berries in Start of 4A (8)", "types": ["checkpoint_berries","midgame"] },
525 { "name": "Use all Binoculars in 4A (3)", "types": ["binoculars","task","midgame"] },
526 { "name": "Grabless Cliff Face", "types": ["grabless"] },
527 { "name": "8 Berries in 3A", "types": ["amount_berries"] }
528],[
529 { "name": "All Berries in Old Trail (7)", "types": ["checkpoint_berries"] },
530 { "name": "Complete 3 A-Sides", "types": ["amount_chapters","midgame"] },
531 { "name": "3 Winged Berries", "types": ["special_berries","earlygame"] },
532 { "name": "All Berries in Presidential Suite (3)", "types": ["checkpoint_berries"] },
533 { "name": "Use 4 Binoculars in B-Sides", "types": ["binoculars"] },
534 { "name": "Use 5 Binoculars in B-Sides", "types": ["binoculars"] },
535 { "name": "5 Berries in 5 Chapters", "types": ["amount_berries"] },
536 { "name": "Huge Mess: Towel -> Books -> Chest", "types": ["huge_mess_pathing"] },
537 { "name": "Huge Mess: Books -> Chest -> Towel", "types": ["huge_mess_pathing"] },
538 { "name": "Jump on 10 Snowballs", "types": ["snowballs"] },
539 { "name": "Jump on 15 Snowballs", "types": ["snowballs"] },
540 { "name": "Get 4 Keys", "types": ["keys"] },
541 { "name": "Get 5 Keys", "types": ["keys"] }
542],[
543 { "name": "2 Seeded Berries", "types": ["special_berries","midgame"] },
544 { "name": "3 Cassettes", "types": ["amount_cassettes"] },
545 { "name": "Golden Ridge Cassette", "types": ["4b","midgame"] },
546 { "name": "25 Berries", "types": ["amount_berries"] },
547 { "name": "30 Berries", "types": ["amount_berries"] },
548 { "name": "Use 2 Binoculars in 2 Chapters", "types": ["binoculars"] },
549 { "name": "Celestial Resort Cassette", "types": ["3b"] },
550 { "name": "Golden Ridge Blue Heart", "types": ["hearts","midgame"] },
551 { "name": "Use 5 Binoculars", "types": ["binoculars"] },
552 { "name": "Use 6 Binoculars", "types": ["binoculars"] },
553 { "name": "3 Blue Hearts", "types": ["amount_hearts"] }
554],[
555 { "name": "Get 2 Keys in 5B", "types": ["5b","task","keys"] },
556 { "name": "Grabless Presidential Suite", "types": ["grabless"] },
557 { "name": "Huge Mess: Books -> Towel -> Chest", "types": ["huge_mess_pathing"] },
558 { "name": "Huge Mess: Towel -> Chest -> Books", "types": ["huge_mess_pathing"] },
559 { "name": "Grabless Search", "types": ["grabless"] },
560 { "name": "4 Winged Berries", "types": ["special_berries"] },
561 { "name": "5 Winged Berries", "types": ["special_berries"] },
562 { "name": "Complete Start of 5A without jumping", "types": ["task","midgame"] },
563 { "name": "Talk to Theo in Search", "types": ["cutscene","search"] },
564 { "name": "All Berries in Cliff Face (5)", "types": ["checkpoint_berries"] }
565],[
566 { "name": "3 Hearts", "types": ["amount_hearts","midgame"] },
567 { "name": "4 Hearts", "types": ["amount_hearts"] },
568 { "name": "Use 6 Binoculars in B-Sides", "types": ["binoculars"] },
569 { "name": "Get 10 Berries in PICO-8", "types": ["pico-8"] },
570 { "name": "Stun Oshiro 10 times", "types": ["oshiro_stun"] },
571 { "name": "Stun Oshiro 15 times", "types": ["oshiro_stun"] },
572 { "name": "Use 1 Binocular in 3 Chapters", "types": ["binoculars","midgame"] },
573 { "name": "Golden Ridge B-Side", "types": ["4b"] },
574 { "name": "Winged Golden Berry", "types": ["challenge"] },
575 { "name": "Grabless Rescue", "types": ["grabless"] }
576],[
577 { "name": "Complete 2 B-Sides", "types": ["amount_chapters"] },
578 { "name": "3 Hearts and 3 Cassettes", "types": ["amount_hearts","amount_cassettes","midgame"] },
579 { "name": "Grabless Depths", "types": ["grabless","midgame"] },
580 { "name": "Grabless Unraveling", "types": ["grabless"] },
581 { "name": "Get the Key in Depths", "types": ["task","keys"] },
582 { "name": "All Berries in Rescue (1)", "types": ["checkpoint_berries"] },
583 { "name": "Mirror Temple Blue Heart", "types": ["hearts"] },
584 { "name": "All Berries in Start of 5A (12)", "types": ["checkpoint_berries"] },
585 { "name": "All Berries in Start of 3A (11)", "types": ["checkpoint_berries"] },
586 { "name": "All Berries in Shrine (9)", "types": ["checkpoint_berries"] },
587 { "name": "4 Blue Hearts", "types": ["amount_hearts"] }
588],[
589 { "name": "All Berries in Unraveling (1)", "types": ["checkpoint_berries"] },
590 { "name": "All Berries in Search (6)", "types": ["checkpoint_berries"] },
591 { "name": "4 Cassettes", "types": ["amount_cassettes"] },
592 { "name": "2 Blue and 2 Red Hearts", "types": ["amount_hearts","amount_chapters"] },
593 { "name": "Get the Orb in PICO-8", "types": ["pico-8"] },
594 { "name": "Get 1 Key in Power Source", "types": ["ch9","binoculars","keys"] },
595 { "name": "Reach Library (3B Checkpoint)", "types": ["3b"] },
596 { "name": "All Berries in Into the Core (1)", "types": ["checkpoint_berries","core"] },
597 { "name": "Reflection Cutscene in Hollows", "types": ["cutscene"] },
598 { "name": "Grabless Lake", "types": ["grabless"] },
599 { "name": "Get 2 Keys in 2 Chapters", "types": ["keys"] }
600],[
601 { "name": "35 Berries", "types": ["amount_berries"] },
602 { "name": "40 Berries", "types": ["amount_berries"] },
603 { "name": "Complete PICO-8", "types": ["pico-8"] },
604 { "name": "3 optional Theo Cutscenes", "types": ["cutscene"] },
605 { "name": "Kill a Seeker", "types": ["seeker","task","midgame"] },
606 { "name": "Use 1 Binocular in 4 Chapters", "types": ["binoculars"] },
607 { "name": "Only top route in Hollows", "types": ["task","reflection_pathing"] },
608 { "name": "Get 1 Key in Search", "types": ["task","search","keys"] },
609 { "name": "Reflection Cassette", "types": ["6b"] },
610 { "name": "Reflection Blue Heart", "types": ["hearts"] },
611 { "name": "Get 6 Keys", "types": ["Keys"] }
612],[
613 { "name": "3 Seeded Berries", "types": ["special_berries","midgame"] },
614 { "name": "Complete 2 A-Sides and 2 B-Sides", "types": ["amount_chapters"] },
615 { "name": "4 Hearts and 4 Cassettes", "types": ["amount_hearts","amount_cassettes"] },
616 { "name": "5 Cassettes", "types": ["amount_cassettes"] },
617 { "name": "Stun Seekers 10 times", "types": ["seeker","task","midgame"] },
618 { "name": "Stun Seekers 15 times", "types": ["seeker","task","midgame"] },
619 { "name": "Get 2 Keys in Power Source", "types": ["ch9","binoculars","keys"] },
620 { "name": "Use 5 Binoculars in Farewell", "types": ["ch9","binoculars"] },
621 { "name": "All Berries in Depths (11)", "types": ["checkpoint_berries"] },
622 { "name": "Mirror Temple B-Side", "types": ["5b","midgame"] },
623 { "name": "Get 3 Keys in 2 Chapters", "types": ["keys"] },
624 { "name": "Get 8 Keys", "types": ["keys"] }
625],[
626 { "name": "5 Hearts", "types": ["amount_hearts"] },
627 { "name": "15 Berries in 5A", "types": ["amount_berries"] },
628 { "name": "20 Berries in 5A", "types": ["amount_berries"] },
629 { "name": "Use 7 Binoculars", "types": ["binoculars"] },
630 { "name": "Use 8 Binoculars", "types": ["binoculars"] },
631 { "name": "Get 15 Berries in PICO-8", "types": ["pico-8","challenge"] },
632 { "name": "Celestial Resort B-Side", "types": ["3b"] },
633 { "name": "Only bottom route in Hollows", "types": ["task","reflection_pathing"] },
634 { "name": "Get 2 Keys in Search", "types": ["task","search","keys"] },
635 { "name": "Get 3 Keys in Search", "types": ["task","search","keys"] },
636 { "name": "Get 8 Keys in A-Sides", "types": ["keys"] }
637],[
638 { "name": "Don't skip final 4A Cutscene", "types": ["cutscene","task"] },
639 { "name": "6 Winged Berries", "types": ["special_berries"] },
640 { "name": "7 Winged Berries", "types": ["special_berries"] },
641 { "name": "All 4 optional Theo Cutscenes", "types": ["cutscene"] },
642 { "name": "Kill 2 different Seekers", "types": ["seeker","task","midgame"] },
643 { "name": "Get 3 Keys in Power Source", "types": ["ch9","binoculars","keys"] },
644 { "name": "Get 4 Keys in Power Source", "types": ["ch9","binoculars","keys"] },
645 { "name": "Use 1 Binocular in 5 Chapters", "types": ["binoculars"] },
646 { "name": "10 Berries in 3 Chapters", "types": ["amount_berries"] },
647 { "name": "Switch to Ice on the right of Into the Core", "types": ["core"] },
648 { "name": "Get 2 Keys in 3 Chapters", "types": ["keys"] }
649],[
650 { "name": "Complete 3 B-Sides", "types": ["amount_chapters"] },
651 { "name": "3 Blue and 3 Red Hearts", "types": ["amount_hearts","amount_chapters"] },
652 { "name": "Complete 2 Chapters Grabless", "types": ["grabless","challenge"] },
653 { "name": "Stun Seekers 20 times", "types": ["seeker","task"] },
654 { "name": "Kill 3 different Seekers", "types": ["seeker","task","midgame"] },
655 { "name": "Use 3 Binoculars in 2 Chapters", "types": ["binoculars"] },
656 { "name": "Blue and Red Heart in Golden Ridge", "types": ["4b"] },
657 { "name": "Grabless Hollows", "types": ["grabless","challenge"] },
658 { "name": "15 Berries in 2 Chapters", "types": ["amount_berries"] },
659 { "name": "15 Berries in 3A", "types": ["amount_berries"] },
660 { "name": "Get 9 keys", "types": ["keys"] },
661 { "name": "Get 10 keys", "types": ["keys"] }
662],[
663 { "name": "Complete 5 A-Sides", "types": ["amount_chapters"] },
664 { "name": "45 Berries", "types": ["amount_berries"] },
665 { "name": "50 Berries", "types": ["amount_berries"] },
666 { "name": "Reach Rock Bottom (6B Checkpoint)", "types": ["6b","lategame"] },
667 { "name": "Use 2 Binoculars in 3 Chapters", "types": ["binoculars"] },
668 { "name": "Blue and Red Heart in Mirror Temple", "types": ["5b"] },
669 { "name": "All Berries in Heart of the Mountain (1)", "types": ["checkpoint_berries","core"] },
670 { "name": "Use all Binoculars in 500M (3)", "types": ["binoculars","lategame"] },
671 { "name": "All Berries in 0M (4)", "types": ["lategame"] },
672 { "name": "Complete Resolution without jumping", "types": ["lategame","task"] },
673 { "name": "Get 4 Keys in 2 Chapters", "types": ["keys"] }
674],[
675 { "name": "8 Winged Berries", "types": ["special_berries"] },
676 { "name": "9 Winged Berries", "types": ["special_berries"] },
677 { "name": "Complete 3 A-Sides and 3 B-Sides", "types": ["amount_chapters"] },
678 { "name": "3 Gems in The Summit", "types": ["lategame","gems"] },
679 { "name": "0M and 500M Gems", "types": ["lategame","gems","task"] },
680 { "name": "Grabless 3A", "types": ["grabless"] },
681 { "name": "10 Berries in 4 Chapters", "types": ["amount_berries"] },
682 { "name": "All Collectibles in 3A", "types": ["amount_berries"] },
683 { "name": "Grabless Rock Bottom", "types": ["lategame","grabless"] },
684 { "name": "Easteregg room in Reflection", "types": ["task"] },
685 { "name": "Get 5 Keys in 2 Chapters", "types": ["keys"] }
686],[
687 { "name": "6 Hearts", "types": ["amount_hearts"] },
688 { "name": "7 Hearts", "types": ["amount_hearts"] },
689 { "name": "20 Berries in 7A", "types": ["lategame"] },
690 { "name": "Use 9 Binoculars", "types": ["binoculars"] },
691 { "name": "Use 10 Binoculars", "types": ["binoculars"] },
692 { "name": "15 Berries in 4A", "types": ["amount_berries"] },
693 { "name": "20 Berries in 4A", "types": ["amount_berries"] },
694 { "name": "Grabless 5A", "types": ["grabless"] },
695 { "name": "All Berries in 500M (6)", "types": ["lategame"] },
696 { "name": "All Berries in 1000M (6)", "types": ["lategame"] },
697 { "name": "Get 12 Keys", "types": ["keys"] }
698],[
699 { "name": "The Summit Cassette", "types": ["7b"] },
700 { "name": "65 Berries", "types": ["amount_berries","big_berries"] },
701 { "name": "75 Berries", "types": ["amount_berries","big_berries"] },
702 { "name": "Visit the Bird's Nest in Epilogue", "types": ["task","lategame"] },
703 { "name": "4 Gems in The Summit", "types": ["lategame","gems"] },
704 { "name": "1000M and 1500M Gems", "types": ["lategame","gems","task"] },
705 { "name": "Blue and Red Heart in Celestial Resort", "types": ["3b"] },
706 { "name": "10 Berries in 5 Chapters", "types": ["amount_berries"] },
707 { "name": "Use 5 Binoculars in The Summit", "types": ["binoculars","lategame"] },
708 { "name": "Use all Binoculars in 1000M (4)", "types": ["binoculars","lategame"] },
709 { "name": "Get 1 Key in 4 Chapters", "types": ["keys"] }
710],[
711 { "name": "Complete 4 B-Sides", "types": ["amount_chapters"] },
712 { "name": "Reflection B-Side", "types": ["6b"] },
713 { "name": "Reach the Intro Car in Remembered", "types": ["ch9","task","challenge"] },
714 { "name": "5 Gems in the Summit", "types": ["lategame","gems"] },
715 { "name": "2000M and 2500M Gems", "types": ["lategame","gems","task"] },
716 { "name": "All Collectibles in 4A", "types": ["amount_berries"] },
717 { "name": "15 Berries in 3 Chapters", "types": ["amount_berries","big_berries"] },
718 { "name": "Grabless 6A", "types": ["lategame","grabless","challenge"] },
719 { "name": "All Berries in 1500M (8)", "types": ["lategame"] },
720 { "name": "All Berries in 2000M (8)", "types": ["lategame"] }
721],[
722 { "name": "35 Berries in 7A", "types": ["lategame"] },
723 { "name": "Blue and Red Heart in Reflection", "types": ["6b"] },
724 { "name": "All Flags in 3000M", "types": ["task","lategame"] },
725 { "name": "All Collectibles in 5A", "types": ["amount_berries"] },
726 { "name": "All Berries in 2500M (8)", "types": ["lategame"] },
727 { "name": "All Berries in 3000M (7)", "types": ["lategame"] },
728 { "name": "All Berries in Hot and Cold (3)", "types": ["checkpoint_berries","core"] },
729 { "name": "Use 2 Binoculars in 4 Chapters", "types": ["binoculars"] },
730 { "name": "Core Blue Heart", "types": ["core"] },
731 { "name": "Get 5 Keys in Power Source", "types": ["ch9","binoculars","keys"] }
732],[
733 { "name": "The Summit B-Side", "types": ["7b"] },
734 { "name": "Blue and Red Heart in The Summit", "types": ["7b"] },
735 { "name": "100 Berries", "types": ["amount_berries","big_berries"] },
736 { "name": "4 Seeded Berries", "types": ["special_berries","lategame"] },
737 { "name": "Complete 5 B-Sides", "types": ["amount_chapters"] },
738 { "name": "15 Berries in 4 Chapters", "types": ["amount_berries","big_berries"] },
739 { "name": "All Collectibles in 7A", "types": ["lategame"] },
740 { "name": "Reach Event Horizon (9 Checkpoint)", "types": ["ch9"] },
741 { "name": "All Collectibles in 8A", "types": ["checkpoint_berries","core"] },
742 { "name": "The Summit Blue Heart", "types": ["gems","hearts"] }
743]];
744
745var bingo = bingoGenerator(bingoList, {});
746console.log(bingo);