branch | transitional_engine |
changeset 16008 | 72c71c385579 |
parent 15978 | 20adaa127663 |
16007:96d0e6149d3d | 16008:72c71c385579 |
---|---|
32 } |
32 } |
33 a { |
33 a { |
34 color: #BFBED0; |
34 color: #BFBED0; |
35 text-decoration: none; |
35 text-decoration: none; |
36 } |
36 } |
37 .hat |
37 .hat, .hatLocal |
38 { |
38 { |
39 margin-top: 12px; |
39 margin-top: 12px; |
40 margin-left: 20px; |
40 margin-left: 20px; |
41 float: left; |
41 float: left; |
42 height: 32px; |
42 height: 32px; |
43 width: 32px; |
43 width: 32px; |
44 color: transparent; |
44 color: transparent; |
45 } |
|
46 .hat |
|
47 { |
|
45 background-image: url("//hg.hedgewars.org/hedgewars/raw-file/tip/share/hedgewars/Data/Graphics/Hedgehog/Idle.png"); |
48 background-image: url("//hg.hedgewars.org/hedgewars/raw-file/tip/share/hedgewars/Data/Graphics/Hedgehog/Idle.png"); |
49 } |
|
50 .hatLocal |
|
51 { |
|
52 background-image: url("../share/hedgewars/Data/Graphics/Hedgehog/Idle.png"); |
|
46 } |
53 } |
47 .girder |
54 .girder |
48 { |
55 { |
49 width: 100%; |
56 width: 100%; |
50 height: 30px; |
57 height: 30px; |
60 width: 32px; |
67 width: 32px; |
61 } |
68 } |
62 </style> |
69 </style> |
63 <script type="application/ecmascript"> |
70 <script type="application/ecmascript"> |
64 //<![CDATA[ |
71 //<![CDATA[ |
65 var IS_LOCAL=false; // set to true to fetch hats locally. Useful for testing. |
72 let IS_LOCAL=false; // set to true to fetch graves locally. Useful for testing. |
66 var masks; |
73 let masks; |
67 if (IS_LOCAL) { |
74 if (IS_LOCAL) { |
68 /* JavaScript version of a sprite sheet - this could be pretty trivially done in pure HTML, but maintenance |
75 /* JavaScript version of a sprite sheet - this could be pretty trivially done in pure HTML, but maintenance |
69 would be easier with a server-side portion. list of sprites could be gotten from server, but would require XSS whitelisting */ |
76 would be easier with a server-side portion. list of sprites could be gotten from server, but would require XSS whitelisting */ |
70 // Last updated: 1.0.0 |
77 // Last updated: 1.0.0 |
71 masks = ['4gsuif','AkuAku','android','angel','anzac','Bandit','barrelhider','bb_bob','bb_bub','bb_cororon','bb_kululun','beefeater','beefeaterhat','bishop','bobby','bobby2v','bubble','bushhider','cap_blue','cap_green','cap_junior','cap_red','cap_thinking','cap_yellow','car','chef','chuckl','clown','clown-copper','clown-crossed','constructor','Coonskin3','Cowboy','cratehider','crown','cyborg1','cyborg2','cyclops','Dan','Dauber','DayAndNight','Disguise','dish_Ladle','dish_SauceBoatSilver','dish_Teacup','dish_Teapot','doctor','Dragon','dwarf','eastertop','Einstein','Elvis','Eva_00b','Eva_00y','Evil','flag_french','flag_germany','flag_italy','flag_usa','footballhelmet','fr_apple','fr_banana','fr_lemon','fr_orange','fr_pumpkin','fr_tomato','Gasmask','Glasses','hair_blue','hair_green','hair_grey','hair_orange','hair_pink','hair_purple','hair_red','hair_yellow','HogInTheHat','hogpharoah','IndianChief','InfernalHorns','Jason','jester','Joker','judo','kiss_criss','kiss_frehley','kiss_simmons','kiss_stanley','knight','lambda','lambdahat','Laminaria','lamp','laurel','leprechaun','mechanicaltoy','MegaHogX','metalband','Meteorhelmet','mexicansunbrero','mickey_ears','Moustache','Moustache_glasses','mp3','Mummy','mv_Spidey','mv_Venom','naruto','NinjaFull','NinjaStraight','NinjaTriangle','noface','ntd_Falcon','ntd_Kirby','ntd_Link','ntd_Samus','nurse','nursehat','OldMan','Pantsu','pinksunhat','pirate_bandana','pirate_eyepatch','pirate_hat','pirate_jack','pirate_jack_bandana','Plunger', |
78 masks = ['4gsuif','AkuAku','android','angel','anzac','Bandit','barrelhider','bb_bob','bb_bub','bb_cororon','bb_kululun','beefeater','beefeaterhat','bishop','bobby','bobby2v','bubble','bushhider','cap_blue','cap_green','cap_junior','cap_red','cap_thinking','cap_yellow','car','chef','chuckl','clown','clown-copper','clown-crossed','constructor','Coonskin3','Cowboy','cratehider','crown','cyborg1','cyborg2','cyclops','Dan','Dauber','DayAndNight','Disguise','dish_Ladle','dish_SauceBoatSilver','dish_Teacup','dish_Teapot','doctor','Dragon','dwarf','eastertop','Einstein','Elvis','Eva_00b','Eva_00y','Evil','flag_french','flag_germany','flag_italy','flag_usa','footballhelmet','fr_apple','fr_banana','fr_lemon','fr_orange','fr_pumpkin','fr_tomato','Gasmask','Glasses','hair_blue','hair_green','hair_grey','hair_orange','hair_pink','hair_purple','hair_red','hair_yellow','HogInTheHat','hogpharoah','IndianChief','InfernalHorns','Jason','jester','Joker','judo','kiss_criss','kiss_frehley','kiss_simmons','kiss_stanley','knight','lambda','lambdahat','Laminaria','lamp','laurel','leprechaun','mechanicaltoy','MegaHogX','metalband','Meteorhelmet','mexicansunbrero','mickey_ears','Moustache','Moustache_glasses','mp3','Mummy','mv_Spidey','mv_Venom','naruto','NinjaFull','NinjaStraight','NinjaTriangle','noface','ntd_Falcon','ntd_Kirby','ntd_Link','ntd_Samus','nurse','nursehat','OldMan','Pantsu','pinksunhat','pirate_bandana','pirate_eyepatch','pirate_hat','pirate_jack','pirate_jack_bandana','Plunger', |
77 else |
84 else |
78 { |
85 { |
79 masks = []; |
86 masks = []; |
80 } |
87 } |
81 |
88 |
82 var themes = { |
89 let themes = { |
83 // Last updated: 1.0.0 |
90 // Last updated: 1.0.0 |
84 "Art":1, |
91 "Art":1, |
85 "Beach":1, |
92 "Beach":1, |
86 "Bamboo":1, |
93 "Bamboo":1, |
87 "Bath":1, |
94 "Bath":1, |
112 "Planes":0, |
119 "Planes":0, |
113 "Sheep":1, |
120 "Sheep":1, |
114 "Snow":1, |
121 "Snow":1, |
115 "Stage":1, |
122 "Stage":1, |
116 "Underwater":1}; |
123 "Underwater":1}; |
117 var girder; |
124 let girder; |
118 var animationInterval; |
125 let animationInterval; |
119 |
126 |
120 var staticMasks = []; |
127 let staticMasks = []; |
121 |
128 |
122 on_xml_loaded = function(ex) |
129 on_xml_loaded = function(ex) |
123 { |
130 { |
124 var resp = this.responseText; |
131 let resp = this.responseText; |
125 var r = />([^<]*).png</g; |
132 let r = />([^<]*).png</g; |
126 var x; |
133 let x; |
127 while(x = r.exec(resp)) |
134 while(x = r.exec(resp)) |
128 { |
135 { |
129 masks.push(x[1]); |
136 masks.push(x[1]); |
130 } |
137 } |
131 on_hats_loaded(); |
138 on_hats_loaded(); |
132 } |
139 } |
133 |
140 |
134 on_xml_error = function() |
141 on_xml_error = function() |
135 { |
142 { |
136 var p = document.createElement("p"); |
143 let p = document.createElement("p"); |
137 p.appendChild(document.createTextNode("ERROR: List of hats could not be fetched from the server!")); |
144 p.appendChild(document.createTextNode("ERROR: List of hats could not be fetched from the server!")); |
138 document.body.appendChild(p); |
145 document.body.appendChild(p); |
139 } |
146 } |
140 |
147 |
141 window.onload = function() |
148 window.onload = function() |
142 { |
149 { |
143 // Load list of hats |
150 // Load list of hats |
144 if (!IS_LOCAL) { |
151 if (!IS_LOCAL) { |
145 // Request list of hats from repository URL |
152 // Request list of hats from repository URL |
146 var xml=new XMLHttpRequest(); |
153 let xml=new XMLHttpRequest(); |
147 xml.open("GET", "//hg.hedgewars.org/hedgewars/file/tip/share/hedgewars/Data/Graphics/Hats/"); |
154 xml.open("GET", "//hg.hedgewars.org/hedgewars/file/tip/share/hedgewars/Data/Graphics/Hats/"); |
148 xml.addEventListener("error", on_xml_error); |
155 xml.addEventListener("error", on_xml_error); |
149 xml.onload = on_xml_loaded; |
156 xml.onload = on_xml_loaded; |
150 xml.send(); |
157 xml.send(); |
151 } |
158 } |
157 |
164 |
158 on_hats_loaded = function() |
165 on_hats_loaded = function() |
159 { |
166 { |
160 // Exclude NoHat as uninteresting. Exclude team hats as we can't properly display them yet |
167 // Exclude NoHat as uninteresting. Exclude team hats as we can't properly display them yet |
161 // TODO: Add support for team hats |
168 // TODO: Add support for team hats |
162 var disallowedMasks = { |
169 let disallowedMasks = { |
163 "NoHat":true, |
170 "NoHat":true, |
164 "hair_team":true, |
171 "hair_team":true, |
165 "cap_team":true, |
172 "cap_team":true, |
166 "TeamTophat":true, |
173 "TeamTophat":true, |
167 }; |
174 }; |
168 |
175 |
169 // Render girders |
176 // Render girders |
170 var s = document.styleSheets[0].cssRules; |
177 let s = document.styleSheets[0].cssRules; |
171 for(var i=0;i<s.length;i++) |
178 for(let i=0;i<s.length;i++) |
172 { |
179 { |
173 if (s[i].selectorText.toLowerCase() === ".girder") |
180 if (s[i].selectorText.toLowerCase() === ".girder") |
174 girder = s[i]; |
181 girder = s[i]; |
175 } |
182 } |
176 |
183 |
177 var a = document.createElement("a"); |
184 let a = document.createElement("a"); |
178 var g = document.createElement("div"); |
185 let g = document.createElement("div"); |
179 g.className="girder"; |
186 g.className="girder"; |
180 a.className="hat"; |
187 if (IS_LOCAL) { |
188 a.className="hatLocal"; |
|
189 } else { |
|
190 a.className="hat"; |
|
191 } |
|
181 a.appendChild(document.createElement("div")); |
192 a.appendChild(document.createElement("div")); |
182 a.lastChild.appendChild(document.createTextNode("")); |
193 a.lastChild.appendChild(document.createTextNode("")); |
183 |
194 |
184 // Render hats |
195 // Render hats |
185 var missingMasks = []; |
196 let missingMasks = []; |
186 var img; |
197 let img; |
187 var j = 0; |
198 let j = 0; |
188 var toDelete = []; |
199 let toDelete = []; |
189 for (var i=0;i<masks.length;i++) |
200 for (let i=0;i<masks.length;i++) |
190 { |
201 { |
191 if (disallowedMasks[masks[i]] === true) { |
202 if (disallowedMasks[masks[i]] === true) { |
192 missingMasks.push(masks[i]); |
203 missingMasks.push(masks[i]); |
193 toDelete.push(i); |
204 toDelete.push(i); |
194 continue; |
205 continue; |
195 } |
206 } |
196 var h = document.body.appendChild(a.cloneNode(true)); |
207 let h = document.body.appendChild(a.cloneNode(true)); |
197 if (IS_LOCAL) |
208 if (IS_LOCAL) |
198 h.href = "../share/hedgewars/Data/Graphics/Hats/"+masks[i]+".png"; |
209 h.href = "../share/hedgewars/Data/Graphics/Hats/"+masks[i]+".png"; |
199 else |
210 else |
200 h.href = "//hg.hedgewars.org/hedgewars/raw-file/tip/share/hedgewars/Data/Graphics/Hats/"+masks[i]+".png"; |
211 h.href = "//hg.hedgewars.org/hedgewars/raw-file/tip/share/hedgewars/Data/Graphics/Hats/"+masks[i]+".png"; |
201 |
212 |
202 img = new Image(); |
213 img = new Image(); |
203 img.onload = function() { |
214 img.onload = function() { |
204 var name = this.id.substr(7); |
215 let name = this.id.substr(7); |
205 if (this.height === 32) { |
216 if (this.height === 32) { |
206 staticMasks[name] = true; |
217 staticMasks[name] = true; |
207 } |
218 } |
208 this.remove(); |
219 this.remove(); |
209 } |
220 } |
210 img.src = h.href; |
221 img.src = h.href; |
211 img.id = "__mask_"+masks[i]; |
222 img.id = "__mask_"+masks[i]; |
212 |
223 |
213 h.lastChild.style.backgroundImage = 'url("'+h.href+'")'; |
224 h.lastChild.style.backgroundImage = 'url("'+h.href+'")'; |
214 h.lastChild.lastChild.data = masks[i]; |
|
215 h.title = masks[i]; |
225 h.title = masks[i]; |
216 h.idle = Math.floor(Math.random()*19); |
226 h.idle = Math.floor(Math.random()*19); |
217 if (j%17 === 16 || i === masks.length-1) |
227 if (j%17 === 16 || i === masks.length-1) |
218 document.body.appendChild(g.cloneNode(false)); |
228 document.body.appendChild(g.cloneNode(false)); |
219 j++; |
229 j++; |
220 } |
230 } |
221 // Cleanup masks array |
231 // Cleanup masks array |
222 for (var i=0; i<toDelete.length; i++) |
232 for (let i=0; i<toDelete.length; i++) |
223 masks.splice(toDelete[i], 1); |
233 masks.splice(toDelete[i], 1); |
224 |
234 |
225 // List missing hats |
235 // List missing hats |
226 if (missingMasks.length > 0) |
236 if (missingMasks.length > 0) |
227 { |
237 { |
228 var pm = document.createElement("p"); |
238 let pm = document.createElement("p"); |
229 pm.appendChild(document.createTextNode("Other hats: ")); |
239 pm.appendChild(document.createTextNode("Other hats: ")); |
230 for (var i=0; i<missingMasks.length; i++) |
240 for (let i=0; i<missingMasks.length; i++) |
231 { |
241 { |
232 if (missingMasks[i] === "NoHat") |
242 if (missingMasks[i] === "NoHat") |
233 continue; |
243 continue; |
234 var link = document.createElement("a"); |
244 let link = document.createElement("a"); |
235 if (IS_LOCAL) |
245 if (IS_LOCAL) |
236 link.href = "../share/hedgewars/Data/Graphics/Hats/"+missingMasks[i]+".png"; |
246 link.href = "../share/hedgewars/Data/Graphics/Hats/"+missingMasks[i]+".png"; |
237 else |
247 else |
238 link.href = "//hg.hedgewars.org/hedgewars/raw-file/tip/share/hedgewars/Data/Graphics/Hats/"+missingMasks[i]+".png"; |
248 link.href = "//hg.hedgewars.org/hedgewars/raw-file/tip/share/hedgewars/Data/Graphics/Hats/"+missingMasks[i]+".png"; |
239 link.appendChild(document.createTextNode(missingMasks[i])); |
249 link.appendChild(document.createTextNode(missingMasks[i])); |
240 pm.appendChild(link); |
250 pm.appendChild(link); |
241 if (i < missingMasks.length -1) |
251 if (i < missingMasks.length -1) |
242 pm.appendChild(document.createTextNode(", ")); |
252 pm.appendChild(document.createTextNode(", ")); |
243 } |
253 } |
254 document.body.appendChild(document.createElement("br")); |
|
244 document.body.appendChild(pm); |
255 document.body.appendChild(pm); |
245 } |
256 } |
246 |
257 |
247 // Quick and dirty animation |
258 // Quick and dirty animation |
248 animationInterval = setInterval(animateHogs, 128); |
259 animationInterval = setInterval(animateHogs, 128); |
249 |
260 |
250 // Theme selection drop-down list |
261 // Theme selection drop-down list |
251 var form = document.body.appendChild(document.createElement("form")); |
262 let form = document.body.appendChild(document.createElement("form")); |
252 |
263 |
253 var opt = document.createElement("option"); |
264 let opt = document.createElement("option"); |
254 opt.appendChild(document.createTextNode("")); |
265 opt.appendChild(document.createTextNode("")); |
255 |
266 |
256 var label = document.createElement("label"); |
267 let label = document.createElement("label"); |
257 label.htmlFor = "theme_select"; |
268 label.htmlFor = "theme_select"; |
258 label.appendChild(document.createTextNode("Theme: ")); |
269 label.appendChild(document.createTextNode("Theme: ")); |
259 form.appendChild(label); |
270 form.appendChild(label); |
260 |
271 |
261 var sel = form.appendChild(document.createElement("select")); |
272 let sel = form.appendChild(document.createElement("select")); |
262 sel.id = "theme_select"; |
273 sel.id = "theme_select"; |
263 sel.onchange = switchTheme; |
274 sel.onchange = switchTheme; |
264 for(var theme in themes) |
275 for(let theme in themes) |
265 { |
276 { |
266 sel.appendChild(opt.cloneNode(true)); |
277 sel.appendChild(opt.cloneNode(true)); |
267 sel.lastChild.value = theme; |
278 sel.lastChild.value = theme; |
268 sel.lastChild.lastChild.data = theme; |
279 sel.lastChild.lastChild.data = theme; |
269 if(theme === "Nature") |
280 if(theme === "Nature") |
270 sel.lastChild.selected = true; |
281 sel.lastChild.selected = true; |
271 } |
282 } |
272 form.appendChild(document.createElement("br")); |
283 form.appendChild(document.createElement("br")); |
273 |
284 |
274 // Checkbox: Switch animation |
285 // Checkbox: Switch animation |
275 var chk = document.createElement("input"); |
286 let chk = document.createElement("input"); |
276 chk.id = "anim"; |
287 chk.id = "anim"; |
277 chk.type = "checkbox"; |
288 chk.type = "checkbox"; |
278 chk.onclick = switchAnim; |
289 chk.onclick = switchAnim; |
279 chk.checked = true; |
290 chk.checked = true; |
280 form.appendChild(chk); |
291 form.appendChild(chk); |
281 label = document.createElement("label"); |
292 label = document.createElement("label"); |
282 label.htmlFor = "anim"; |
293 label.htmlFor = "anim"; |
283 label.appendChild(document.createTextNode("Animate hats")); |
294 label.appendChild(document.createTextNode(" Animate hats")); |
284 form.appendChild(label); |
295 form.appendChild(label); |
285 |
296 |
286 form.appendChild(document.createElement("br")); |
297 form.appendChild(document.createElement("br")); |
287 |
298 |
288 // Checkbox: Hide girders |
299 // Checkbox: Hide girders |
292 chk.onclick = hideGirders; |
303 chk.onclick = hideGirders; |
293 chk.checked = true; |
304 chk.checked = true; |
294 form.appendChild(chk); |
305 form.appendChild(chk); |
295 label = document.createElement("label"); |
306 label = document.createElement("label"); |
296 label.htmlFor = "hide_girders"; |
307 label.htmlFor = "hide_girders"; |
297 label.appendChild(document.createTextNode("Show girders")); |
308 label.appendChild(document.createTextNode(" Show girders")); |
298 form.appendChild(label); |
309 form.appendChild(label); |
299 |
310 |
300 document.body.appendChild(form); |
311 document.body.appendChild(form); |
301 |
312 |
302 |
313 switchTheme(); |
303 } |
314 } |
304 |
315 |
305 function animateHogs() |
316 function animateHogs() |
306 { |
317 { |
307 var a = document.getElementsByTagName("a"); |
318 let a = document.getElementsByTagName("a"); |
308 for (var i=0;i<a.length;i++) |
319 for (let i=0;i<a.length;i++) |
309 { |
320 { |
310 if (a[i].className !== "hat") |
321 if (a[i].className !== "hat" && a[i].className !== "hatLocal") |
311 continue; |
322 continue; |
312 // Cycle through hedgehog and hat animation frames |
323 // Cycle through hedgehog and hat animation frames |
313 |
324 |
314 // Hedgehog |
325 // Hedgehog |
315 a[i].style.backgroundPosition=Math.floor(a[i].idle/16)*-32+"px "+(a[i].idle%16)*-32+"px"; |
326 a[i].style.backgroundPosition=Math.floor(a[i].idle/16)*-32+"px "+(a[i].idle%16)*-32+"px"; |
316 |
327 |
317 var maskName = a[i].title; |
328 let maskName = a[i].title; |
318 // Hat |
329 // Hat |
319 if (staticMasks[maskName] === true) { |
330 if (staticMasks[maskName] === true) { |
320 // Hat offset for static hats |
331 // Hat offset for static hats |
321 if (a[i].idle === 2 || a[i].idle === 7 || a[i].idle === 12) |
332 if (a[i].idle === 2 || a[i].idle === 7 || a[i].idle === 12) |
322 a[i].firstChild.style.marginTop="-4px"; |
333 a[i].firstChild.style.marginTop="-4px"; |
352 } |
363 } |
353 |
364 |
354 // Turn on or off girders |
365 // Turn on or off girders |
355 function hideGirders() |
366 function hideGirders() |
356 { |
367 { |
357 var g = document.getElementsByClassName("girder"); |
368 let g = document.getElementsByClassName("girder"); |
358 for(var i=0;i<g.length;i++) |
369 for(let i=0;i<g.length;i++) |
359 if (this.checked) |
370 if (this.checked) |
360 g[i].className = "girder"; |
371 g[i].className = "girder"; |
361 else |
372 else |
362 g[i].className = "girder hide"; |
373 g[i].className = "girder hide"; |
363 |
374 |
364 } |
375 } |
365 |
376 |
366 // Select theme according to drop-down list value |
377 // Select theme according to drop-down list value |
367 function switchTheme() |
378 function switchTheme() |
368 { |
379 { |
369 var prefix; |
380 let prefix; |
370 if (!IS_LOCAL) |
381 if (!IS_LOCAL) |
371 prefix = "//hg.hedgewars.org/hedgewars/raw-file/tip"; |
382 prefix = "//hg.hedgewars.org/hedgewars/raw-file/tip"; |
372 else |
383 else |
373 prefix = ".."; |
384 prefix = ".."; |
374 document.body.style.backgroundImage='url("'+prefix+'/share/hedgewars/Data/Themes/'+this.value+'/Sky.png")'; |
385 let theme = this.value || "Nature"; |
375 if (themes[this.value]) |
386 document.body.style.backgroundImage='url("'+prefix+'/share/hedgewars/Data/Themes/'+theme+'/Sky.png")'; |
376 girder.style.backgroundImage='url("'+prefix+'/share/hedgewars/Data/Themes/'+this.value+'/Girder.png")'; |
387 if (themes[theme]) |
388 girder.style.backgroundImage='url("'+prefix+'/share/hedgewars/Data/Themes/'+theme+'/Girder.png")'; |
|
377 else |
389 else |
378 girder.style.backgroundImage='url("'+prefix+'/share/hedgewars/Data/Graphics/Girder.png")'; |
390 girder.style.backgroundImage='url("'+prefix+'/share/hedgewars/Data/Graphics/Girder.png")'; |
379 } |
391 } |
380 //]]> |
392 //]]> |
381 </script> |
393 </script> |