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