]> git.localhorst.tv Git - alttp.git/blob - resources/js/components/common/ZeldaIcon.js
tentative inverted logic
[alttp.git] / resources / js / components / common / ZeldaIcon.js
1 import PropTypes from 'prop-types';
2 import React from 'react';
3 import { useTranslation } from 'react-i18next';
4
5 import Icon from './Icon';
6
7 const ITEM_MAP = [
8     'aga',
9     'armos',
10     'arrghus',
11     'big-key',
12     'blind',
13     'blue-boomerang',
14     'blue-mail',
15     'blue-pendant',
16     'blue-potion',
17     'bombos',
18     'bomb',
19     'book',
20     'boots',
21     'bottle-bee',
22     'bottle-good-bee',
23     'bottle',
24     'bowless-silvers',
25     'bow',
26     'bugnet',
27     'bunny-head',
28     'byrna',
29     'cape',
30     'chest',
31     'compass',
32     'crystal',
33     'crystal-switch-blue',
34     'crystal-switch',
35     'crystal-switch-red',
36     'duck',
37     'ether',
38     'fairy',
39     'fighter-shield',
40     'fighter-sword',
41     'fire-rod',
42     'fire-shield',
43     'flippers',
44     'flute',
45     'ganon',
46     'glove',
47     'gold-sword',
48     'green-mail',
49     'green-pendant',
50     'green-potion',
51     'gt',
52     'half-magic',
53     'hammer',
54     'heart-0',
55     'heart-1',
56     'heart-2',
57     'heart-3',
58     'heart-container',
59     'heart-piece',
60     'helma',
61     'hookshot',
62     'ice-rod',
63     'kholdstare',
64     'lamp',
65     'lanmolas',
66     'link-head',
67     'map',
68     'master-sword',
69     'mirror',
70     'mirror-shield',
71     'mitts',
72     'moldorm',
73     'moonpearl',
74     'mothula',
75     'mushroom',
76     'open-chest',
77     'powder',
78     'quake',
79     'quarter-magic',
80     'red-bomb',
81     'red-boomerang',
82     'red-crystal',
83     'red-mail',
84     'red-pendant',
85     'red-potion',
86     'shovel',
87     'silvers',
88     'small-key',
89     'somaria',
90     'sword-1',
91     'sword-2',
92     'sword-3',
93     'sword-4',
94     'tempered-sword',
95     'triforce-piece',
96     'triforce',
97     'trinexx',
98     'vitreous',
99 ];
100
101 const ITEM_MAP_WIDTH = 8;
102
103 const ITEM_MAP_HEIGHT = Math.ceil(ITEM_MAP.length / ITEM_MAP_WIDTH);
104
105 const ITEM_MAP_URL = '/items-v2.png';
106
107 const isOnItemMap = name => ITEM_MAP.includes(name);
108
109 const getItemMapX = name => ITEM_MAP.indexOf(name) % ITEM_MAP_WIDTH;
110
111 const getItemMapY = name => Math.floor(ITEM_MAP.indexOf(name) / ITEM_MAP_WIDTH);
112
113 const getItemMapStyle = name => {
114         const x = getItemMapX(name);
115         const y = getItemMapY(name);
116         return {
117                 backgroundImage: `url(${ITEM_MAP_URL})`,
118                 backgroundPosition: `-${x * 100}% -${y * 100}%`,
119                 backgroundSize: `${ITEM_MAP_WIDTH * 100}% ${ITEM_MAP_HEIGHT * 100}%`,
120         };
121 };
122
123 const getIconURL = name => {
124         switch (name) {
125                 case 'dungeon-ct':
126                 case 'dungeon-dp':
127                 case 'dungeon-ep':
128                 case 'dungeon-gt':
129                 case 'dungeon-hc':
130                 case 'dungeon-ip':
131                 case 'dungeon-mm':
132                 case 'dungeon-pd':
133                 case 'dungeon-sp':
134                 case 'dungeon-sw':
135                 case 'dungeon-th':
136                 case 'dungeon-tr':
137                 case 'dungeon-tt':
138                         return `/dungeon/${name.substr(8)}.png`;
139                 default:
140                         return '';
141         }
142 };
143
144 const ZeldaIcon = ({ name, svg, title }) => {
145         const { t } = useTranslation();
146
147         const invert = name.startsWith('not-');
148         const strippedName = invert ? name.substr(4) : name;
149         const src = getIconURL(strippedName);
150         const alt = t(`icon.zelda.${name}`);
151         const realTitle = title !== '' ? title || alt : null;
152
153         if (svg) {
154                 const clipX = getItemMapX(strippedName);
155                 const clipY = getItemMapY(strippedName);
156                 return <image
157                         href={isOnItemMap(strippedName) ? ITEM_MAP_URL : src}
158                         width={ITEM_MAP_WIDTH}
159                         height={ITEM_MAP_HEIGHT}
160                         x="0"
161                         y="0"
162                         transform={`translate(-${clipX} -${clipY})`}
163                         clipPath={`xywh(${clipX + 0.02} ${clipY + 0.02} 0.96 0.96)`}
164                 >
165                         {realTitle ?
166                                 <title>{realTitle}</title>
167                         : null}
168                 </image>;
169         }
170
171         return <span className="zelda-icon">
172                 {isOnItemMap(strippedName) ?
173                         <span
174                                 className="item-map-icon"
175                                 style={getItemMapStyle(strippedName)}
176                                 title={realTitle}
177                         />
178                 : null}
179                 {src ?
180                         <img
181                                 alt={alt}
182                                 src={src}
183                                 title={realTitle}
184                         />
185                 : null}
186                 {invert ?
187                         <span className="strike">
188                                 <Icon.SLASH title="" />
189                         </span>
190                 : null}
191         </span>;
192 };
193
194 ZeldaIcon.propTypes = {
195         name: PropTypes.string.isRequired,
196         svg: PropTypes.bool,
197         title: PropTypes.string,
198 };
199
200 export default ZeldaIcon;