1 export const RAM_ADDR = {
3 FREE_ITEM_MENU: 0x180045,
11 export const SRAM_ADDR = {
12 ROOM_DATA_START: 0x000,
15 PYRAMID_SCREEN: 0x2DB,
21 export const WRAM_ADDR = {
23 CURRENT_DUNGEON: 0x10E,
27 export const INV_ADDR = {
73 SMALL_KEY_START: 0x3C,
79 RANDO_KEY_START: 0x1A0,
83 export const DUNGEON_IDS = {
100 export const DUNGEON_MASKS = {
117 export const ABILITY_MASKS = {
125 export const IN_GAME_MODES = [
126 0x05, // loading game
127 0x06, // entering dungeon
129 0x08, // entering overworld
131 0x0A, // entering special overworld
132 0x0B, // special overworld
133 0x0E, // text/menu/map
134 0x0F, // closing spot
135 0x10, // opening spot
142 0x18, // aga 2 cutscene
143 0x19, // triforce room
144 0x1B, // spawn select
147 export const getShort = (data, offset) => (data[offset] * 256) + data[offset + 1];
149 export const buildPrizeMap = (prizes, crystals) => {
151 Object.entries(DUNGEON_IDS).forEach(([, id]) => {
152 const isCrystal = !!(crystals && crystals[id]);
153 const mask = (prizes && prizes[id]) || 0;
154 map[id] = { isCrystal, mask };
159 export const isBossDefeated = (data, room) => {
160 return !!(data && (data[(2 * room) + 1] & 0x08));
163 export const isChestOpen = (data, room, chest) => {
165 return !!(data && (data[2 * room] & Math.pow(2, chest + 4)));
167 return !!(data && (data[(2 * room) + 1] & Math.pow(2, chest - 4)));
171 export const hasVisitedQuadrant = (data, room, quadrant) => {
172 return !!(data && (data[2 * room] & Math.pow(2, quadrant - 1)));
175 export const GT_BASEMENT_CHECKS = [
200 export const GT_BASEMENT_ALL = [
226 export const getGTBasementState = (data) => ({
227 iceM: isChestOpen(data, 0x1C, 0),
228 iceL: isChestOpen(data, 0x1C, 1),
229 iceR: isChestOpen(data, 0x1C, 2),
230 dmUL: isChestOpen(data, 0x7B, 0),
231 dmUR: isChestOpen(data, 0x7B, 1),
232 dmBL: isChestOpen(data, 0x7B, 2),
233 dmBR: isChestOpen(data, 0x7B, 3),
234 randoUL: isChestOpen(data, 0x7C, 0),
235 randoUR: isChestOpen(data, 0x7C, 1),
236 randoBL: isChestOpen(data, 0x7C, 2),
237 randoBR: isChestOpen(data, 0x7C, 3),
238 fireSnake: isChestOpen(data, 0x7D, 0),
239 mapChest: isChestOpen(data, 0x8B, 0),
240 hopeL: isChestOpen(data, 0x8C, 1),
241 hopeR: isChestOpen(data, 0x8C, 2),
242 bobsChest: isChestOpen(data, 0x8C, 3),
243 torchSeen: hasVisitedQuadrant(data, 0x8C, 4),
244 torch: isChestOpen(data, 0x8C, 6),
245 tileRoom: isChestOpen(data, 0x8D, 0),
246 compassUL: isChestOpen(data, 0x9D, 0),
247 compassUR: isChestOpen(data, 0x9D, 1),
248 compassBL: isChestOpen(data, 0x9D, 2),
249 compassBR: isChestOpen(data, 0x9D, 3),
252 export const countGTBasementState = (state) =>
253 GT_BASEMENT_CHECKS.reduce((acc, cur) => state[cur] ? acc + 1 : acc, 0);
255 export const compareGTBasementState = (prev, cur) => {
256 for (let i = 0; i < GT_BASEMENT_ALL.length; ++i) {
257 if (prev[GT_BASEMENT_ALL[i]] !== cur[GT_BASEMENT_ALL[i]]) {
258 return GT_BASEMENT_ALL[i];