'blue-potion',
'fairy',
'bottle-bee',
- 'bottle-bee',
+ 'bottle-good-bee',
];
export const BOSSES = [
export const CONFIG = {
bossShuffle: false,
+ checkCalculation: 'room-data',
glitches: 'none',
+ mapLayout: 'horizontal',
showMap: 'situational',
showCompass: 'situational',
showSmall: 'always',
export const getConfigValue = (config, name, fallback) =>
Object.prototype.hasOwnProperty.call(config, name) ? config[name] : fallback;
+export const configureDungeons = config => DUNGEONS.map(dungeon => {
+ const newDungeon = JSON.parse(JSON.stringify(dungeon));
+ if (config.wildMap && dungeon.map) {
+ ++newDungeon.items;
+ }
+ if (config.wildCompass && dungeon.compass) {
+ ++newDungeon.items;
+ }
+ if (config.wildSmall) {
+ newDungeon.items += dungeon.sk;
+ }
+ if (config.wildBig && dungeon.bk && !dungeon.dropBk) {
+ ++newDungeon.items;
+ }
+ if (dungeon.boss) {
+ newDungeon.bosses = config.bossShuffle ? BOSSES : [dungeon.boss];
+ }
+ return newDungeon;
+});
+
export const applyLogic = (config, dungeons, state) => {
const logic = Logic[config.worldState];
const map = {};
case 'always':
return true;
case 'situational':
- return wild;
+ return wild || (which === 'Compass' && config.bossShuffle);
case 'never':
return false;
}
state[`${dungeon.id}-compass`] = !!(compass & dungeon.mask);
state[`${dungeon.id}-small-key`] = data[INV_ADDR.RANDO_KEY_START + dungeon.offset];
state[`${dungeon.id}-big-key`] = !!(bigKey & dungeon.mask);
+ state[`${dungeon.id}-checks-collected`] =
+ data[INV_ADDR.RANDO_CHECKS_START + dungeon.offset];
if (dungeon.prize) {
const isCrystal = prizeMap[dungeon.offset].isCrystal;
const prizeFlags = data[isCrystal ? INV_ADDR.CRYSTALS : INV_ADDR.PENDANTS];
- state[`${dungeon.id}-prize-acquired`] = !!(prizeFlags & prizeMap[dungeon.offset].mask);
+ const prizeAcquired = !!(prizeFlags & prizeMap[dungeon.offset].mask);
+ state[`${dungeon.id}-prize-acquired`] = prizeAcquired;
+ if (prizeAcquired) {
+ if (!isCrystal) {
+ if (prizeMap[dungeon.offset].mask === 1) {
+ state[`${dungeon.id}-prize`] = 'red-pendant';
+ } else if (prizeMap[dungeon.offset].mask === 2) {
+ state[`${dungeon.id}-prize`] = 'blue-pendant';
+ } else if (prizeMap[dungeon.offset].mask === 4) {
+ state[`${dungeon.id}-prize`] = 'green-pendant';
+ }
+ } else {
+ state[`${dungeon.id}-prize`] = 'crystal';
+ }
+ }
}
});
};
});
};
-export const computeState = (config, data, prizeMap) => {
- const state = {};
- collectInventory(state, data.slice(SRAM_ADDR.INV_START), prizeMap);
- collectOverworld(state, data);
- collectUnderworld(state, data.slice(SRAM_ADDR.ROOM_DATA_START));
- const amounts = getDungeonAmounts(config, state);
- DUNGEONS.forEach(dungeon => {
- state[`${dungeon.id}-checks`] = amounts[dungeon.id];
- });
- return state;
-};
-
const getDungeonAmounts = (config, state) => {
const amounts = {};
DUNGEONS.forEach(dungeon => {
let amount = 0;
let total = dungeon.checks.length;
- dungeon.checks.forEach(check => {
- if (state[check]) {
- ++amount;
- }
- });
+ if (config.checkCalculation === 'inventory') {
+ amount = state[`${dungeon.id}-checks-collected`];
+ } else {
+ dungeon.checks.forEach(check => {
+ if (state[check]) {
+ ++amount;
+ }
+ });
+ }
if (!config.wildMap && state[`${dungeon.id}-map`]) {
--amount;
--total;
return amounts;
};
+export const computeState = (config, data, prizeMap) => {
+ const state = {};
+ collectInventory(state, data.slice(SRAM_ADDR.INV_START), prizeMap);
+ collectOverworld(state, data);
+ collectUnderworld(state, data.slice(SRAM_ADDR.ROOM_DATA_START));
+ const amounts = getDungeonAmounts(config, state);
+ DUNGEONS.forEach(dungeon => {
+ state[`${dungeon.id}-checks`] = amounts[dungeon.id];
+ });
+ return state;
+};
+
export const mergeStates = (autoState, manualState) => {
const next = { ...autoState };
BOOLEAN_STATES.forEach(name => {