--- /dev/null
+export const isChestOpen = (data, room, chest) => {
+ if (chest < 4) {
+ return !!(data && (data[2 * room] & Math.pow(2, chest + 4)));
+ } else {
+ return !!(data && (data[(2 * room) + 1] & Math.pow(2, chest - 4)));
+ }
+};
+
+export const hasVisitedQuadrant = (data, room, quadrant) => {
+ return !!(data && (data[2 * room] & Math.pow(2, quadrant - 1)));
+};
+
+export const GT_BASEMENT_CHECKS = [
+ 'iceM',
+ 'iceL',
+ 'iceR',
+ 'dmUL',
+ 'dmUR',
+ 'dmBL',
+ 'dmBR',
+ 'randoUL',
+ 'randoUR',
+ 'randoBL',
+ 'randoBR',
+ 'fireSnake',
+ 'mapChest',
+ 'hopeL',
+ 'hopeR',
+ 'bobsChest',
+ 'torchSeen',
+ 'tileRoom',
+ 'compassUL',
+ 'compassUR',
+ 'compassBL',
+ 'compassBR',
+];
+
+export const GT_BASEMENT_ALL = [
+ 'iceM',
+ 'iceL',
+ 'iceR',
+ 'dmUL',
+ 'dmUR',
+ 'dmBL',
+ 'dmBR',
+ 'randoUL',
+ 'randoUR',
+ 'randoBL',
+ 'randoBR',
+ 'fireSnake',
+ 'mapChest',
+ 'hopeL',
+ 'hopeR',
+ 'bobsChest',
+ 'torch',
+ 'torchSeen',
+ 'tileRoom',
+ 'compassUL',
+ 'compassUR',
+ 'compassBL',
+ 'compassBR',
+];
+
+export const getGTBasementState = (data) => ({
+ iceM: isChestOpen(data, 0x1C, 0),
+ iceL: isChestOpen(data, 0x1C, 1),
+ iceR: isChestOpen(data, 0x1C, 2),
+ dmUL: isChestOpen(data, 0x7B, 0),
+ dmUR: isChestOpen(data, 0x7B, 1),
+ dmBL: isChestOpen(data, 0x7B, 2),
+ dmBR: isChestOpen(data, 0x7B, 3),
+ randoUL: isChestOpen(data, 0x7C, 0),
+ randoUR: isChestOpen(data, 0x7C, 1),
+ randoBL: isChestOpen(data, 0x7C, 2),
+ randoBR: isChestOpen(data, 0x7C, 3),
+ fireSnake: isChestOpen(data, 0x7D, 0),
+ mapChest: isChestOpen(data, 0x8B, 0),
+ hopeL: isChestOpen(data, 0x8C, 1),
+ hopeR: isChestOpen(data, 0x8C, 2),
+ bobsChest: isChestOpen(data, 0x8C, 3),
+ torchSeen: hasVisitedQuadrant(data, 0x8C, 4),
+ torch: isChestOpen(data, 0x8C, 6),
+ tileRoom: isChestOpen(data, 0x8D, 0),
+ compassUL: isChestOpen(data, 0x9D, 0),
+ compassUR: isChestOpen(data, 0x9D, 1),
+ compassBL: isChestOpen(data, 0x9D, 2),
+ compassBR: isChestOpen(data, 0x9D, 3),
+});
+
+export const countGTBasementState = (state) =>
+ GT_BASEMENT_CHECKS.reduce((acc, cur) => state[cur] ? acc + 1 : acc, 0);
+
+export const compareGTBasementState = (prev, cur) => {
+ for (let i = 0; i < GT_BASEMENT_ALL.length; ++i) {
+ if (prev[GT_BASEMENT_ALL[i]] !== cur[GT_BASEMENT_ALL[i]]) {
+ return GT_BASEMENT_ALL[i];
+ }
+ }
+ return '';
+};