X-Git-Url: https://git.localhorst.tv/?a=blobdiff_plain;f=resources%2Fjs%2Fcomponents%2Ftracker%2FMap.js;h=b77612ef65bd02ae9eb481df3c8e90b28daf4bb1;hb=249e06be11d0f7778d99956c87d4f0a8ac7e69f7;hp=520ad938ab2faaafb61fd3774626af442104aa5b;hpb=3603709307e0777958cd18134ad4178cef410d14;p=alttp.git diff --git a/resources/js/components/tracker/Map.js b/resources/js/components/tracker/Map.js index 520ad93..b77612e 100644 --- a/resources/js/components/tracker/Map.js +++ b/resources/js/components/tracker/Map.js @@ -3,11 +3,20 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; import { + addDungeonCheck, clearAll, - decrement, + completeDungeonChecks, + countRemainingLocations, + getDungeonClearedItems, + getDungeonRemainingItems, + hasClearedLocations, hasDungeonBoss, - increment, - toggleBoolean, + hasDungeonPrize, + isDungeonCleared, + removeDungeonCheck, + resetDungeonChecks, + setBossDefeated, + setPrizeAcquired, unclearAll, } from '../../helpers/tracker'; import { useTracker } from '../../hooks/tracker'; @@ -636,8 +645,8 @@ const Location = ({ number, l, size }) => { > {t(`tracker.location.${l.id}`)} - {number && l.cleared < l.total ? - {Math.max(0, l.total - l.cleared)} + {number && l.remaining ? + {l.remaining} : null} ; }; @@ -648,8 +657,8 @@ Location.propTypes = { id: PropTypes.string, x: PropTypes.number, y: PropTypes.number, - cleared: PropTypes.number, - total: PropTypes.number, + number: PropTypes.number, + remaining: PropTypes.number, status: PropTypes.string, handlePrimary: PropTypes.func, handleSecondary: PropTypes.func, @@ -657,92 +666,113 @@ Location.propTypes = { size: PropTypes.string, }; +const makeBackground = (src, level) => { + const amount = Math.pow(2, Math.max(0, level - 8)); + const size = 1 / amount; + const tiles = []; + for (let y = 0; y < amount; ++y) { + for (let x = 0; x < amount; ++x) { + tiles.push(); + } + } + return tiles; +}; + const Map = () => { - const { dungeons, setState, state } = useTracker(); + const { dungeons, setManualState, state } = useTracker(); const mapDungeon = React.useCallback(dungeon => { const definition = dungeons.find(d => d.id === dungeon.id); - const cleared = state[`${dungeon.id}-checks`] || 0; - const total = definition.items; + const remaining = getDungeonRemainingItems(state, definition); let status = 'available'; - if (cleared === total) { - if (['ct', 'gt'].includes(dungeon.id)) { - if (hasDungeonBoss(state, dungeon)) { - status = 'cleared'; - } - } else { - status = 'cleared'; - } + if (isDungeonCleared(state, definition)) { + status = 'cleared'; } return { ...dungeon, status, - cleared, - total, + remaining, handlePrimary: () => { - if (['ct', 'gt'].includes(dungeon.id) && cleared === total) { - if (hasDungeonBoss(state, dungeon)) { - // reset - setState(s => ({ - ...s, - [`${dungeon.id}-checks`]: 0, - [`${dungeon.id}-boss-defeated`]: false, - })); - } else { - setState(toggleBoolean(`${dungeon.id}-boss-defeated`)); + if (getDungeonRemainingItems(state, definition)) { + setManualState(addDungeonCheck(definition)); + } else if ( + !hasDungeonBoss(state, definition) || !hasDungeonPrize(state, definition) + ) { + if (definition.boss) { + setManualState(setBossDefeated(definition, true)); + } + if (definition.prize) { + setManualState(setPrizeAcquired(definition, true)); } } else { - setState(increment(`${dungeon.id}-checks`, total)); + setManualState(resetDungeonChecks(definition)); + if (definition.boss) { + setManualState(setBossDefeated(definition, false)); + } + if (definition.prize) { + setManualState(setPrizeAcquired(definition, false)); + } } }, handleSecondary: () => { - if (['ct', 'gt'].includes(dungeon.id) && - (hasDungeonBoss(state, dungeon) || !cleared) - ) { - if (hasDungeonBoss(state, dungeon)) { - setState(toggleBoolean(`${dungeon.id}-boss-defeated`)); - } else { - setState(s => ({ - ...s, - [`${dungeon.id}-checks`]: total, - [`${dungeon.id}-boss-defeated`]: true, - })); + if (isDungeonCleared(state, definition)) { + if (definition.items) { + setManualState(removeDungeonCheck(definition)); + } + if (definition.boss) { + setManualState(setBossDefeated(definition, false)); } + if (definition.prize) { + setManualState(setPrizeAcquired(definition, false)); + } + } else if (getDungeonClearedItems(state, definition)) { + setManualState(removeDungeonCheck(definition)); } else { - setState(decrement(`${dungeon.id}-checks`, total)); + setManualState(completeDungeonChecks(definition)); + if (definition.boss) { + setManualState(setBossDefeated(definition, true)); + } + if (definition.prize) { + setManualState(setPrizeAcquired(definition, true)); + } } }, }; - }, [dungeons, setState, state]); + }, [dungeons, setManualState, state]); const mapLocation = React.useCallback(loc => { - const cleared = loc.checks.reduce((acc, cur) => state[cur] ? acc + 1 : acc, 0); - const total = loc.checks.length; + const remaining = countRemainingLocations(state, loc.checks); let status = 'available'; - if (cleared === total) { + if (hasClearedLocations(state, loc.checks)) { status = 'cleared'; } return { ...loc, - cleared, - total, + remaining, status, handlePrimary: () => { - if (cleared < total) { - setState(clearAll(loc.checks)); + if (remaining) { + setManualState(clearAll(loc.checks)); } else { - setState(unclearAll(loc.checks)); + setManualState(unclearAll(loc.checks)); } }, handleSecondary: () => { - if (cleared < total) { - setState(clearAll(loc.checks)); + if (remaining) { + setManualState(clearAll(loc.checks)); } else { - setState(unclearAll(loc.checks)); + setManualState(unclearAll(loc.checks)); } }, }; - }, [setState, state]); + }, [setManualState, state]); const lwDungeons = React.useMemo(() => LW_DUNGEONS.map(mapDungeon), [mapDungeon]); const lwLocations = React.useMemo(() => LW_LOCATIONS.map(mapLocation), [mapLocation]); @@ -764,34 +794,7 @@ const Map = () => { > - - - - + {makeBackground('lw_files', 10)} {lwLocations.map(l => @@ -804,34 +807,7 @@ const Map = () => { - - - - + {makeBackground('dw_files', 10)} {dwLocations.map(l =>