]> git.lizzy.rs Git - dragonblocks.git/blob - engine/mainmenu.js
Code style overhaul
[dragonblocks.git] / engine / mainmenu.js
1 /*
2  * mainmenu.js
3  *
4  * Copyright 2020 Elias Fleckenstein <eliasfleckenstein@web.de>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19  * MA 02110-1301, USA.
20  *
21  *
22  */
23
24 {
25         document.title = dragonblocks.version.string;
26
27         let mainmenu = document.body.insertBefore(document.createElement("div"), document.body.firstChild);
28         mainmenu.style.visibility = "hidden";
29
30         let center = mainmenu.appendChild(document.createElement("center"));
31
32         let logo = center.appendChild(document.createElement("img"));
33         logo.src = "textures/logo-mainmenu.png";
34
35         let status = center.appendChild(document.createElement("h1"));
36         status.style.fontSize = "50px";
37         status.style.display = "none";
38
39         let content = center.appendChild(document.createElement("div"));
40         content.id = "dragonblocks.mainmenu.content";
41         content.style.position = "relative";
42         content.style.top = "50px";
43
44         let buttons = [];
45         let onReload = [];
46
47         let clearChildren = parent => {
48                 while (elem = parent.firstChild)
49                         elem.remove();
50         };
51
52         // Load World Button
53
54         {
55                 let loadWorldGUI, worldlistDisplay, noWorldsNotice;
56
57                 if (dragonblocks.loggedin) {
58                         onReload.push(_ => {
59                                 if (loadWorldGUI) {
60                                         clearChildren(worldlistDisplay);
61                                 } else {
62                                         loadWorldGUI = new dragonblocks.gui.Box();
63
64                                         let headline = loadWorldGUI.create("h1");
65                                         headline.innerHTML = "Select World";
66                                         headline.align = "center";
67
68                                         noWorldsNotice = loadWorldGUI.create("center").appendChild(document.createElement("b"));
69
70                                         worldlistDisplay = loadWorldGUI.create("ul");
71                                 }
72
73                                 noWorldsNotice.innerHTML = dragonblocks.worlds.length == 0 ? "No Worlds" : "";
74
75                                 for (let worldname in dragonblocks.worlds) {
76                                         let world = dragonblocks.worlds[worldname];
77
78                                         if (world.owned) {
79                                                 let worldDisplay = worldlistDisplay.appendChild(document.createElement("li"));
80                                                 worldDisplay.style.fontSize = "20px";
81                                                 worldDisplay.textContent = world.name;
82                                                 worldDisplay.style.postion = "relative";
83
84                                                 let button = worldDisplay.appendChild(document.createElement("button"));
85                                                 button.textContent = "Play";
86                                                 button.style.position = "absolute";
87                                                 button.style.right = "5px";
88                                                 button.style.fontSize = "12px";
89                                                 button.addEventListener("click", event => {
90                                                         event.srcElement.blur();
91                                                         loadWorldGUI.close();
92
93                                                         dragonblocks.worldIsLoaded = true;
94                                                         dragonblocks.worldname = world.name;
95                                                         dragonblocks.world = $.getJSON("worlds/" + worldname + "/world.json").responseJSON;
96
97                                                         dragonblocks.mods = dragonblocks.world.mods;
98
99                                                         dragonblocks.start();
100                                                 });
101                                         }
102                                 }
103                         });
104                 }
105
106                 buttons.push({
107                         text: "Load Saved World",
108                         action: _ => {
109                                 loadWorldGUI.open()
110                         },
111                         disabled: ! dragonblocks.loggedin,
112                 })
113         }
114
115         // Create World Button
116
117         {
118                 let createWorldGUI = new dragonblocks.gui.Box();
119                 let createButton;
120
121                 let worldProperties = {};
122
123                 let headline = createWorldGUI.create("h1");
124                 headline.innerHTML = "New World";
125                 headline.align = "center";
126
127                 // Worldname
128                 createWorldGUI.create("h2").innerHTML = "&ensp;World Name";
129
130                 let worldnameInput = createWorldGUI.create("input");
131                 worldnameInput.type = "text";
132                 worldnameInput.style.position = "relative";
133                 worldnameInput.style.left = "40px";
134
135                 let worldnameAlert = createWorldGUI.create("b");
136                 worldnameAlert.style.position = "relative";
137                 worldnameAlert.style.left = "50px";
138
139                 worldnameInput.addEventListener("input", _ => {
140                         let worldname = worldnameInput.value;
141
142                         if(! dragonblocks.loggedin) {
143                                 worldnameAlert.textContent = "Warning: You are not logged in and cannot save worlds.";
144                                 worldnameAlert.style.color = "#FF7D00";
145                                 createButton.disabled = false;
146                         } else if (worldname == "") {
147                                 worldnameAlert.textContent = "";
148                                 createButton.disabled = true;
149                         } else if (! dragonblocks.checkWorldnameSpelling(worldname)) {
150                                 worldnameAlert.textContent = "The world name contains forbidden characters";
151                                 worldnameAlert.style.color = "#FF001F";
152                                 createButton.disabled = true;
153                         } else if (dragonblocks.worlds[worldname]) {
154                                 if (dragonblocks.worlds[worldname].owned) {
155                                         worldnameAlert.textContent = "Warning: This will overwrite an existing world";
156                                         worldnameAlert.style.color = "#FF7D00";
157                                         createButton.disabled = false;
158                                 } else {
159                                         worldnameAlert.textContent = "This Worldname is taken";
160                                         worldnameAlert.style.color = "#FF001F";
161                                         createButton.disabled = true;
162                                 }
163                         } else {
164                                 worldnameAlert.textContent = "";
165                                 createButton.disabled = false;
166                         }
167
168                         worldProperties.worldname = worldname;
169                 });
170
171                 // Mods
172                 worldProperties.mods = {};
173
174                 createWorldGUI.create("h2").innerHTML = "&ensp;Mods";
175
176                 let modlistDisplay;
177
178                 let updateModlist = _ => {
179                         if (modlistDisplay)
180                                 clearChildren(modlistDisplay);
181                         else
182                                 modlistDisplay = createWorldGUI.create("ul");
183
184                         let oldSelectedMods = worldProperties.mods;
185                         worldProperties.mods = {};
186
187                         for (let modname in dragonblocks.mods) {
188                                 let modinfo = dragonblocks.mods[modname];
189
190                                 let modDisplay = modlistDisplay.appendChild(document.createElement("li"));
191                                 modDisplay.style.fontSize = "20px";
192                                 modDisplay.innerHTML = mod;
193                                 modDisplay.style.postion = "relative";
194                                 modDisplay.title = modinfo.description;
195
196                                 let checkbox = modDisplay.appendChild(document.createElement("input"));
197                                 checkbox.type = "checkbox";
198                                 checkbox.style.position = "absolute";
199                                 checkbox.style.right = "5px";
200
201                                 checkbox.addEventListener("input", _ => {
202                                         worldProperties.mods[mod] = checkbox.checked;
203                                 });
204
205                                 worldProperties.mods[mod] = checkbox.checked = oldSelectedMods[mod];
206                         }
207                 };
208
209                 // Gamemode
210                 worldProperties.gamemode = "survival";
211
212                 createWorldGUI.create("h2").innerHTML = "&ensp;Gamemode";
213
214                 for (let gamemode of ["survival", "creative"]){
215                         let radiobox = createWorldGUI.create("input");
216                         radiobox.name = "dragonblocks.mainmenu.createWorldGUI.gamemode";
217                         radiobox.type = "radio";
218                         radiobox.checked = gamemode == worldProperties.gamemode;
219                         radiobox.style.position = "relative";
220                         radiobox.style.left = "40px";
221
222                         radiobox.addEventListener("input", _ => {
223                                 if (radiobox.checked)
224                                         worldProperties.gamemode = gamemode;
225                         });
226
227                         let label = createWorldGUI.create("label");
228                         label.innerHTML = dblib.humanFormat(gamemode);
229                         label.style.position = "relative";
230                         label.style.left = "40px";
231                 }
232
233                 // Mapgen
234                 createWorldGUI.create("h2").innerHTML = "&ensp;Mapgen";
235
236                 let selectMapgen = createWorldGUI.create("select");
237                 selectMapgen.style.position = "relative";
238                 selectMapgen.style.left = "40px";
239
240                 selectMapgen.addEventListener("input", _ => {
241                         worldProperties.mapgen = selectMapgen.value;
242                 });
243
244                 for (let mapgen in dragonblocks.mapgen.list)
245                         selectMapgen.appendChild(document.createElement("option")).innerHTML = mapgen;
246
247                 worldProperties.mapgen = selectMapgen.value;
248
249                 createWorldGUI.create("br");
250                 createWorldGUI.create("br");
251
252                 // Create Button
253                 createButton = createWorldGUI.create("button");
254                 createButton.style.position = "absolute";
255                 createButton.style.left = "1%";
256                 createButton.style.bottom = "5px";
257                 createButton.style.width = "98%";
258                 createButton.style.fontSize = "20px";
259                 createButton.innerHTML = "Create World";
260
261                 createButton.addEventListener("click", event => {
262                         event.srcElement.blur();
263                         createWorldGUI.close();
264
265                         dragonblocks.worldIsLoaded = false;
266                         dragonblocks.worldname = worldProperties.worldname;
267                         dragonblocks.world = dragonblocks.getEmptyWorld();
268
269                         dragonblocks.entities["dragonblocks:player"].meta.creative = (worldProperties.gamemode == "creative");
270
271                         dragonblocks.mapgen.selected = worldProperties.mapgen;
272
273                         dragonblocks.start(worldProperties.mods);
274                 });
275
276                 createWorldGUI.create("br");
277                 createWorldGUI.create("br");
278
279                 onReload.push(_ => {
280                         worldnameInput.value = "";
281                         worldnameAlert.textContent = "";
282                         createButton.disabled = dragonblocks.loggedin;
283
284                         updateModlist();
285                 });
286
287                 buttons.push({
288                         text: "Create New World",
289                         action: _ => {
290                                 createWorldGUI.open();
291                         },
292                 });
293         }
294
295         // Credits Button
296
297         {
298                 let creditsGUI = new dragonblocks.gui.Box();
299
300                 let pages = $.getJSON("credits.json").responseJSON;
301                 let page = 0;
302
303                 for (let dir of ["left", "right"]) {
304                         let arrow = creditsGUI.create("div");
305                         arrow.style.position = "absolute";
306                         arrow.style.width = "80px";
307                         arrow.style.height = "80px";
308                         arrow.style.position = "absolute";
309                         arrow.style[dir] = "3px";
310                         arrow.style.background = dragonblocks.getTexture("arrow.png");
311                         arrow.style.backgroundSize = "cover";
312                         arrow.style.cursor = "pointer";
313
314                         if (dir == "right")
315                                 arrow.style.transform = "rotate(180deg)";
316
317                         arrow.addEventListener("click", _ => {
318                                 if (dir == "right")
319                                         page++;
320                                 else
321                                         page--;
322
323                                 creditsGUI.open();
324                         });
325
326                         dblib.centerVertical(arrow);
327                 }
328
329                 let creditsContent = creditsGUI.create("center");
330
331                 creditsGUI.addEventListener("open", _ => {
332                         if (page < 0)
333                                 page = pages.length - 1;
334                         else if (page >= pages.length)
335                                 page = 0;
336
337                         creditsContent.innerHTML = pages[page];
338                         dragonblocks.resolveTextures(creditsContent);
339
340                         // fix to center the dots of the li elements in chromium as well
341
342                         let lis = creditsContent.getElementsByTagName("li");
343
344                         for (let li of lis)
345                                 li.style.width = "max-content";
346                 });
347
348                 buttons.push({
349                         text: "Credits",
350                         action: _ => {
351                                 creditsGUI.open();
352                         },
353                 });
354         }
355
356         // Quit Button
357
358         {
359                 buttons.push({
360                         text: "Quit",
361                         action: _ => {
362                                 if (dragonblocks.isChromeApp)
363                                         window.close();
364                                 else
365                                         history.back();
366                         },
367                 });
368         }
369
370         for (let {text, action, disabled} of buttons) {
371                 let button = content.appendChild(document.createElement("button"));
372                 button.style.fontSize = "40px";
373                 button.style.width = "100%";
374                 button.innerHTML = text;
375                 button.disabled = disabled;
376                 button.addEventListener("click", action);
377
378                 content.appendChild(document.createElement("br"));
379                 content.appendChild(document.createElement("br"));
380         }
381
382         for (let [side, text] of [["left", dragonblocks.version.string], ["right", dragonblocks.version.copyright]]) {
383                 let notice = content.appendChild(document.createElement("span"));
384                 notice.style.position = "fixed";
385                 notice.style.bottom = "5px";
386                 notice.style[side] = "5px";
387                 notice.innerHTML = text;
388         }
389
390         dragonblocks.enterMainMenu = _ => {
391                 dragonblocks.loadModList();
392                 dragonblocks.loadWorldList();
393
394                 content.style.display = "inherit";
395                 status.style.display = "none";
396
397                 for (let func of onReload)
398                         func();
399         };
400
401         dragonblocks.registerOnStart(_ => {
402                 content.style.display = "none";
403                 status.style.display = "inherit";
404
405                 status.innerHTML = "Loading...";
406         });
407
408         dragonblocks.registerOnStarted(_ => {
409                 mainmenu.style.visibility = "hidden";
410         });
411
412         dragonblocks.registerOnQuit(_ => {
413                 mainmenu.style.visibility = "visible";
414                 status.innerHTML = "Saving...";
415         });
416
417         let initMainMenu = _ => {
418                 document.body.style.backgroundColor = "skyblue";
419                 document.getElementById("elidragon").remove();
420                 content.style.width = logo.offsetWidth + "px";
421                 mainmenu.style.visibility = "visible";
422
423                 dragonblocks.enterMainMenu();
424         };
425
426         if (logo.complete)
427                 initMainMenu();
428         else
429                 logo.addEventListener("load", initMainMenu);
430 }