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_CHECKS_START: 0x180,
80 RANDO_CHECKS_END: 0x18F,
81 RANDO_KEY_START: 0x1A0,
85 export const DUNGEON_IDS = {
102 export const DUNGEON_MASKS = {
119 export const ABILITY_MASKS = {
127 export const IN_GAME_MODES = [
128 0x05, // loading game
129 0x06, // entering dungeon
131 0x08, // entering overworld
133 0x0A, // entering special overworld
134 0x0B, // special overworld
135 0x0E, // text/menu/map
136 0x0F, // closing spot
137 0x10, // opening spot
144 0x18, // aga 2 cutscene
145 0x19, // triforce room
146 0x1B, // spawn select
149 export const getShort = (data, offset) => (data[offset] * 256) + data[offset + 1];
151 export const buildPrizeMap = (prizes, crystals) => {
153 Object.entries(DUNGEON_IDS).forEach(([, id]) => {
154 const isCrystal = !!(crystals && crystals[id]);
155 const mask = (prizes && prizes[id]) || 0;
156 map[id] = { isCrystal, mask };
161 export const isBossDefeated = (data, room) => {
162 return !!(data && (data[(2 * room) + 1] & 0x08));
165 export const isChestOpen = (data, room, chest) => {
167 return !!(data && (data[2 * room] & Math.pow(2, chest + 4)));
169 return !!(data && (data[(2 * room) + 1] & Math.pow(2, chest - 4)));
173 export const hasVisitedQuadrant = (data, room, quadrant) => {
174 return !!(data && (data[2 * room] & Math.pow(2, quadrant - 1)));
177 export const GT_BASEMENT_CHECKS = [
202 export const GT_BASEMENT_ALL = [
228 export const getGTBasementState = (data) => ({
229 iceM: isChestOpen(data, 0x1C, 0),
230 iceL: isChestOpen(data, 0x1C, 1),
231 iceR: isChestOpen(data, 0x1C, 2),
232 dmUL: isChestOpen(data, 0x7B, 0),
233 dmUR: isChestOpen(data, 0x7B, 1),
234 dmBL: isChestOpen(data, 0x7B, 2),
235 dmBR: isChestOpen(data, 0x7B, 3),
236 randoUL: isChestOpen(data, 0x7C, 0),
237 randoUR: isChestOpen(data, 0x7C, 1),
238 randoBL: isChestOpen(data, 0x7C, 2),
239 randoBR: isChestOpen(data, 0x7C, 3),
240 fireSnake: isChestOpen(data, 0x7D, 0),
241 mapChest: isChestOpen(data, 0x8B, 0),
242 hopeL: isChestOpen(data, 0x8C, 1),
243 hopeR: isChestOpen(data, 0x8C, 2),
244 bobsChest: isChestOpen(data, 0x8C, 3),
245 torchSeen: hasVisitedQuadrant(data, 0x8C, 4),
246 torch: isChestOpen(data, 0x8C, 6),
247 tileRoom: isChestOpen(data, 0x8D, 0),
248 compassUL: isChestOpen(data, 0x9D, 0),
249 compassUR: isChestOpen(data, 0x9D, 1),
250 compassBL: isChestOpen(data, 0x9D, 2),
251 compassBR: isChestOpen(data, 0x9D, 3),
254 export const countGTBasementState = (state) =>
255 GT_BASEMENT_CHECKS.reduce((acc, cur) => state[cur] ? acc + 1 : acc, 0);
257 export const compareGTBasementState = (prev, cur) => {
258 for (let i = 0; i < GT_BASEMENT_ALL.length; ++i) {
259 if (prev[GT_BASEMENT_ALL[i]] !== cur[GT_BASEMENT_ALL[i]]) {
260 return GT_BASEMENT_ALL[i];