];
export const INTEGER_STATES = [
- 'bottle',
+ 'bottle-1',
+ 'bottle-2',
+ 'bottle-3',
+ 'bottle-4',
'heart-piece',
'lift',
'mail',
mail: 1,
};
+export const BOTTLE_CONTENTS = [
+ 'mushroom',
+ 'bottle',
+ 'red-potion',
+ 'green-potion',
+ 'blue-potion',
+ 'fairy',
+ 'bottle-bee',
+ 'bottle-good-bee',
+];
+
export const BOSSES = [
'armos',
'lanmolas',
},
];
+export const getConfigValue = (config, name, fallback) =>
+ Object.prototype.hasOwnProperty.call(config, name) ? config[name] : fallback;
+
export const applyLogic = (config, dungeons, state) => {
const logic = Logic[config.worldState];
const map = {};
for (const name in logic) {
- map[name] = logic[name](config, dungeons, state);
+ try {
+ map[name] = logic[name](config, dungeons, state);
+ } catch (e) {
+ console.error('error evaluating', name, e);
+ }
}
return map;
};
if (statuses.filter(s => ['available', 'cleared'].includes(s)).length === statuses.length) {
return 'available';
}
- if (statuses.filter(s => s === 'unavailable').length === statuses.length) {
+ if (statuses.filter(s => ['unavailable', 'cleared'].includes(s)).length === statuses.length) {
return 'unavailable';
}
return 'partial';
export const countRemainingLocations = (state, locations) =>
locations.reduce((acc, cur) => state[cur] ? acc : acc + 1, 0);
-export const getGanonCrystals = (state) => state['ganon-crystals'];
+export const getGanonCrystals = (config) => getConfigValue(config, 'ganon-crystals', 7);
-export const getGTCrystals = (state) => state['gt-crystals'];
+export const getGTCrystals = (config) => getConfigValue(config, 'gt-crystals', 7);
export const getGTBoss = (state, which) => state[`gt-${which}-boss`];
!dungeon.boss || !!state[`${dungeon.id}-boss-defeated`];
export const getDungeonBoss = (state, dungeon) =>
- state[`${dungeon.id}-boss`] || dungeon.boss || null;
+ dungeon.bosses.length > 1
+ ? state[`${dungeon.id}-boss`] || dungeon.boss || null
+ : dungeon.bosses[0];
export const hasDungeonPrize = (state, dungeon) =>
!dungeon.prize || !!state[`${dungeon.id}-prize-acquired`];
});
state['mm-medallion'] = null;
state['tr-medallion'] = null;
- state['gt-crystals'] = 7;
- state['ganon-crystals'] = 7;
return state;
};
state.duck = !!(data[INV_ADDR.RANDO_FLUTE] & 0x01);
state.bugnet = !!data[INV_ADDR.BUGNET];
state.book = !!data[INV_ADDR.BOOK];
- state.bottle = 0;
- if (data[INV_ADDR.BOTTLE_1]) {
- ++state.bottle;
- }
- if (data[INV_ADDR.BOTTLE_2]) {
- ++state.bottle;
- }
- if (data[INV_ADDR.BOTTLE_3]) {
- ++state.bottle;
- }
- if (data[INV_ADDR.BOTTLE_4]) {
- ++state.bottle;
- }
+ state['bottle-1'] = data[INV_ADDR.BOTTLE_1];
+ state['bottle-2'] = data[INV_ADDR.BOTTLE_2];
+ state['bottle-3'] = data[INV_ADDR.BOTTLE_3];
+ state['bottle-4'] = data[INV_ADDR.BOTTLE_4];
state.somaria = !!data[INV_ADDR.SOMARIA];
state.byrna = !!data[INV_ADDR.BYRNA];
state.cape = !!data[INV_ADDR.CAPE];
if (manualState[`${dungeon.id}-map`]) {
next[`${dungeon.id}-map`] = true;
}
+ if (manualState[`${dungeon.id}-boss`]) {
+ next[`${dungeon.id}-boss`] = manualState[`${dungeon.id}-boss`];
+ }
if (manualState[`${dungeon.id}-boss-defeated`]) {
next[`${dungeon.id}-boss-defeated`] = true;
}
next[loc.id] = true;
}
});
+ // prefer auto
+ next['bottle-1'] = autoState['bottle-1'] || manualState['bottle-1'] || 0;
+ next['bottle-2'] = autoState['bottle-2'] || manualState['bottle-2'] || 0;
+ next['bottle-3'] = autoState['bottle-3'] || manualState['bottle-3'] || 0;
+ next['bottle-4'] = autoState['bottle-4'] || manualState['bottle-4'] || 0;
+ // force manual
next['mm-medallion'] = manualState['mm-medallion'];
next['tr-medallion'] = manualState['tr-medallion'];
next['gt-crystals'] = manualState['gt-crystals'];
next['ganon-crystals'] = manualState['ganon-crystals'];
+ next['gt-bot-boss'] = manualState['gt-bot-boss'];
+ next['gt-mid-boss'] = manualState['gt-mid-boss'];
+ next['gt-top-boss'] = manualState['gt-top-boss'];
//console.log(next);
return next;
};