]> git.localhorst.tv Git - alttp.git/blobdiff - resources/js/pages/DoorsTracker.js
improved directory structure
[alttp.git] / resources / js / pages / DoorsTracker.js
diff --git a/resources/js/pages/DoorsTracker.js b/resources/js/pages/DoorsTracker.js
new file mode 100644 (file)
index 0000000..be98f82
--- /dev/null
@@ -0,0 +1,188 @@
+import React from 'react';
+import { Helmet } from 'react-helmet';
+
+import ZeldaIcon from '../components/common/ZeldaIcon';
+
+const DUNGEONS = [
+       'hc',
+       'ct',
+       'ep',
+       'dp',
+       'th',
+       'pd',
+       'sp',
+       'sw',
+       'tt',
+       'ip',
+       'mm',
+       'tr',
+       'gt',
+];
+
+const ITEMS = [
+       'compass',
+       'map',
+       'big-key',
+       'bow',
+       'hookshot',
+       'fire-rod',
+       'lamp',
+       'hammer',
+       'somaria',
+       'fighter-sword',
+       'boots',
+       'glove',
+       'flippers',
+];
+
+const ITEM_CLASSES = {
+       'compass': 'dungeon-item',
+       'map': 'dungeon-item',
+       'big-key': 'dungeon-item',
+       'bow': 'item',
+       'hookshot': 'item',
+       'fire-rod': 'item',
+       'lamp': 'item',
+       'hammer': 'item',
+       'somaria': 'item',
+       'fighter-sword': 'item',
+       'boots': 'item',
+       'glove': 'item',
+       'flippers': 'item',
+};
+
+const nextCSwitch = cur => {
+       switch (cur) {
+               case 'blue':
+                       return 'red';
+               case 'red':
+                       return '';
+               default:
+                       return 'blue';
+       }
+};
+
+const prevCSwitch = cur => nextCSwitch(nextCSwitch(cur));
+
+const DoorsTracker = () => {
+       const [state, setState] = React.useState(DUNGEONS.reduce((state, dungeon) => ({
+               ...state,
+               [dungeon]: ITEMS.reduce((items, item) => ({
+                       ...items,
+                       [item]: false,
+               }), {
+                       boss: true,
+                       cswitch: '',
+                       keys: 1,
+               }),
+       }), {}));
+
+       const handleItemClick = React.useCallback((dungeon, item) => e => {
+               setState(state => ({
+                       ...state,
+                       [dungeon]: {
+                               ...state[dungeon],
+                               [item]: !state[dungeon][item],
+                       },
+               }));
+               e.preventDefault();
+               e.stopPropagation();
+       });
+
+       const handleCSwitchClick = React.useCallback(dungeon => e => {
+               setState(state => ({
+                       ...state,
+                       [dungeon]: {
+                               ...state[dungeon],
+                               cswitch: nextCSwitch(state[dungeon].cswitch),
+                       },
+               }));
+               e.preventDefault();
+               e.stopPropagation();
+       });
+
+       const handleCSwitchRightClick = React.useCallback(dungeon => e => {
+               setState(state => ({
+                       ...state,
+                       [dungeon]: {
+                               ...state[dungeon],
+                               cswitch: prevCSwitch(state[dungeon].cswitch),
+                       },
+               }));
+               e.preventDefault();
+               e.stopPropagation();
+       });
+
+       const handleKeysClick = React.useCallback(dungeon => e => {
+               setState(state => ({
+                       ...state,
+                       [dungeon]: {
+                               ...state[dungeon],
+                               keys: state[dungeon].keys + 1,
+                       },
+               }));
+               e.preventDefault();
+               e.stopPropagation();
+       });
+
+       const handleKeysRightClick = React.useCallback(dungeon => e => {
+               setState(state => ({
+                       ...state,
+                       [dungeon]: {
+                               ...state[dungeon],
+                               keys: Math.max(state[dungeon].keys - 1, 0),
+                       },
+               }));
+               e.preventDefault();
+               e.stopPropagation();
+       });
+
+       return <>
+               <Helmet>
+                       <title>Doors Tracker</title>
+                       <meta name="description" content="Doors Tracker" />
+               </Helmet>
+               <div className="doors-tracker d-flex flex-column">
+                       {DUNGEONS.map(dungeon =>
+                               <div className="d-flex flex-row" key={dungeon}>
+                                       <div
+                                               className={`cell ${state[dungeon].boss ? 'on' : 'off'} dungeon`}
+                                               onClick={handleItemClick(dungeon, 'boss')}
+                                       >
+                                               <ZeldaIcon name={`dungeon-${dungeon}`} />
+                                       </div>
+                                       <div
+                                               className={`cell ${state[dungeon].keys ? 'on' : 'off'} keys`}
+                                               onClick={handleKeysClick(dungeon)}
+                                               onContextMenu={handleKeysRightClick(dungeon)}
+                                       >
+                                               {state[dungeon].keys}
+                                       </div>
+                                       <div
+                                               className={`cell ${state[dungeon].cswitch ? 'on' : 'off'} cswitch`}
+                                               onClick={handleCSwitchClick(dungeon)}
+                                               onContextMenu={handleCSwitchRightClick(dungeon)}
+                                       >
+                                               <ZeldaIcon name={state[dungeon].cswitch
+                                                       ? `crystal-switch-${state[dungeon].cswitch}`
+                                                       : 'crystal-switch'
+                                               } />
+                                       </div>
+                                       {ITEMS.map(item =>
+                                               <div
+                                                       className={
+                                                               `cell ${state[dungeon][item] ? 'on' : 'off'} ${ITEM_CLASSES[item]}`
+                                                       }
+                                                       key={item}
+                                                       onClick={handleItemClick(dungeon, item)}
+                                               >
+                                                       <ZeldaIcon name={item} />
+                                               </div>
+                                       )}
+                               </div>
+                       )}
+               </div>
+       </>;
+};
+
+export default DoorsTracker;