]> git.localhorst.tv Git - alttp.git/blobdiff - resources/js/helpers/tracker.js
add good bee visual
[alttp.git] / resources / js / helpers / tracker.js
index 47a34f135bbd55e7ec3eb31f2efccc7a824eccfe..6a927bc056b9680a9e7ec5acf9e6377c2d2256b6 100644 (file)
@@ -43,7 +43,10 @@ export const BOOLEAN_STATES = [
 ];
 
 export const INTEGER_STATES = [
-       'bottle',
+       'bottle-1',
+       'bottle-2',
+       'bottle-3',
+       'bottle-4',
        'heart-piece',
        'lift',
        'mail',
@@ -55,6 +58,17 @@ export const INITIAL = {
        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',
@@ -1559,11 +1573,18 @@ export const UNDERWORLD_LOCATIONS = [
        },
 ];
 
+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;
 };
@@ -1647,7 +1668,7 @@ export const getCombinedStatus = statuses => {
        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';
@@ -1661,9 +1682,9 @@ export const aggregateLocationStatus = (names, logic, state) => {
 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`];
 
@@ -1671,7 +1692,9 @@ export const hasDungeonBoss = (state, dungeon) =>
        !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`];
@@ -1762,8 +1785,6 @@ export const makeEmptyState = () => {
        });
        state['mm-medallion'] = null;
        state['tr-medallion'] = null;
-       state['gt-crystals'] = 7;
-       state['ganon-crystals'] = 7;
        return state;
 };
 
@@ -1789,19 +1810,10 @@ const collectInventory = (state, data, prizeMap) => {
        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];
@@ -1912,6 +1924,9 @@ export const mergeStates = (autoState, manualState) => {
                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;
                }
@@ -1936,10 +1951,19 @@ export const mergeStates = (autoState, manualState) => {
                        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;
 };