]> git.localhorst.tv Git - alttp.git/blob - resources/js/hooks/tracker.js
ec1e8ce25c2a6725c5ebbd726377eb6a890755ad
[alttp.git] / resources / js / hooks / tracker.js
1 import PropTypes from 'prop-types';
2 import React from 'react';
3
4 import {
5         BOSSES,
6         CONFIG,
7         DUNGEONS,
8         applyLogic,
9         makeEmptyState,
10         mergeStates,
11 } from '../helpers/tracker';
12
13 const context = React.createContext({});
14
15 export const useTracker = () => React.useContext(context);
16
17 export const TrackerProvider = ({ children }) => {
18         const [config, setConfig] = React.useState(CONFIG);
19         const [state, setState] = React.useState(makeEmptyState());
20         const [autoState, setAutoState] = React.useState(makeEmptyState());
21         const [manualState, setManualState] = React.useState(makeEmptyState());
22         const [dungeons, setDungeons] = React.useState(DUNGEONS);
23         const [logic, setLogic] = React.useState({});
24
25         const saveConfig = React.useCallback((values) => {
26                 setConfig(s => {
27                         const newConfig = { ...s, ...values };
28                         localStorage.setItem('tracker.config', JSON.stringify(newConfig));
29                         return newConfig;
30                 });
31         }, []);
32
33         React.useEffect(() => {
34                 const savedConfig = localStorage.getItem('tracker.config');
35                 if (savedConfig) {
36                         setConfig(c => ({ ...c, ...JSON.parse(savedConfig) }));
37                 }
38         }, []);
39
40         React.useEffect(() => {
41                 const newDungeons = DUNGEONS.map(dungeon => {
42                         const newDungeon = JSON.parse(JSON.stringify(dungeon));
43                         if (config.wildMap && dungeon.map) {
44                                 ++newDungeon.items;
45                         }
46                         if (config.wildCompass && dungeon.compass) {
47                                 ++newDungeon.items;
48                         }
49                         if (config.wildSmall) {
50                                 newDungeon.items += dungeon.sk;
51                         }
52                         if (config.wildBig && dungeon.bk && !dungeon.dropBk) {
53                                 ++newDungeon.items;
54                         }
55                         if (dungeon.boss) {
56                                 newDungeon.bosses = config.bossShuffle ? BOSSES : [dungeon.boss];
57                         }
58                         return newDungeon;
59                 });
60                 setDungeons(newDungeons);
61         }, [config]);
62
63         React.useEffect(() => {
64                 setState(mergeStates(autoState, manualState));
65         }, [autoState, manualState]);
66
67         React.useEffect(() => {
68                 setLogic(applyLogic(config, dungeons, state));
69         }, [config, dungeons, state]);
70
71         const value = React.useMemo(() => {
72                 return { config, dungeons, logic, saveConfig, setAutoState, setManualState, state };
73         }, [config, dungeons, logic, state]);
74
75         return <context.Provider value={value}>
76                 {children}
77         </context.Provider>;
78 };
79
80 TrackerProvider.propTypes = {
81         children: PropTypes.node,
82 };