4 * Copyright 2020 Elias Fleckenstein <eliasfleckenstein@web.de>
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.
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.
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,
25 document.title = dragonblocks.version.string;
27 let mainmenu = document.body.insertBefore(document.createElement("div"), document.body.firstChild);
28 mainmenu.style.visibility = "hidden";
30 let center = mainmenu.appendChild(document.createElement("center"));
32 let logo = center.appendChild(document.createElement("img"));
33 logo.src = "textures/logo-mainmenu.png";
35 let splash = mainmenu.appendChild(document.createElement("div"));
36 splash.style.position = "fixed";
37 splash.style.overflow = "hidden";
38 splash.style.whiteSpace = "nowrap";
39 splash.style.transform = "rotate(-15deg)";
40 splash.style.color = "yellow";
41 splash.style.fontSize = "30px";
43 let status = center.appendChild(document.createElement("h1"));
44 status.style.fontSize = "50px";
45 status.style.display = "none";
47 let content = center.appendChild(document.createElement("div"));
48 content.id = "dragonblocks.mainmenu.content";
49 content.style.position = "relative";
50 content.style.top = "50px";
55 let clearChildren = parent => {
56 while (elem = parent.firstChild)
65 let loadWorldGUI, worldlistDisplay, noWorldsNotice;
67 let worldProperties = new dragonblocks.World.Properties(true);
69 if (dragonblocks.loggedin) {
72 clearChildren(worldlistDisplay);
74 loadWorldGUI = new dragonblocks.gui.Box();
76 let headline = loadWorldGUI.create("h1");
77 headline.innerHTML = "Select World";
78 headline.align = "center";
80 noWorldsNotice = loadWorldGUI.create("center").appendChild(document.createElement("b"));
82 worldlistDisplay = loadWorldGUI.create("ul");
85 noWorldsNotice.innerHTML = worlds.length == 0 ? "No Worlds" : "";
87 for (let worldname in worlds) {
88 let world = worlds[worldname];
91 let worldDisplay = worldlistDisplay.appendChild(document.createElement("li"));
92 worldDisplay.style.fontSize = "20px";
93 worldDisplay.textContent = world.name;
94 worldDisplay.style.postion = "relative";
96 let button = worldDisplay.appendChild(document.createElement("button"));
97 button.textContent = "Play";
98 button.style.position = "absolute";
99 button.style.right = "5px";
100 button.style.fontSize = "12px";
101 button.addEventListener("click", event => {
102 event.srcElement.blur();
103 loadWorldGUI.close();
105 worldProperties.name = world.name;
106 dragonblocks.start(worldProperties);
114 text: "Load Saved World",
118 disabled: ! dragonblocks.loggedin,
122 // Create World Button
125 let createWorldGUI = new dragonblocks.gui.Box();
128 let worldProperties = new dragonblocks.World.Properties(false);
130 let headline = createWorldGUI.create("h1");
131 headline.innerHTML = "New World";
132 headline.align = "center";
135 createWorldGUI.create("h2").innerHTML = " World Name";
137 let worldnameInput = createWorldGUI.create("input");
138 worldnameInput.type = "text";
139 worldnameInput.style.position = "relative";
140 worldnameInput.style.left = "40px";
142 let worldnameAlert = createWorldGUI.create("b");
143 worldnameAlert.style.position = "relative";
144 worldnameAlert.style.left = "50px";
146 worldnameInput.addEventListener("input", _ => {
147 worldProperties.name = worldnameInput.value;
149 if (! dragonblocks.loggedin) {
150 worldnameAlert.textContent = "Warning: You are not logged in and cannot save worlds.";
151 worldnameAlert.style.color = "#FF7D00";
152 createButton.disabled = false;
153 } else if (worldProperties.name == "") {
154 worldnameAlert.textContent = "";
155 createButton.disabled = true;
156 } else if (! worldProperties.checkSpelling()) {
157 worldnameAlert.textContent = "The world name contains forbidden characters";
158 worldnameAlert.style.color = "#FF001F";
159 createButton.disabled = true;
160 } else if (worlds[worldProperties.name]) {
161 if (worlds[worldProperties.name].owned) {
162 worldnameAlert.textContent = "Warning: This will overwrite an existing world";
163 worldnameAlert.style.color = "#FF7D00";
164 createButton.disabled = false;
166 worldnameAlert.textContent = "This Worldname is taken";
167 worldnameAlert.style.color = "#FF001F";
168 createButton.disabled = true;
171 worldnameAlert.textContent = "";
172 createButton.disabled = false;
177 createWorldGUI.create("h2").innerHTML = " Mods";
179 let modlistDisplay = createWorldGUI.create("ul");
181 let updateModlist = _ => {
182 clearChildren(modlistDisplay);
184 let oldSelectedMods = worldProperties.mods;
185 worldProperties.mods = {};
187 for (let modname in dragonblocks.mods) {
188 let modinfo = dragonblocks.mods[modname];
190 let modDisplay = modlistDisplay.appendChild(document.createElement("li"));
191 modDisplay.style.fontSize = "20px";
192 modDisplay.innerHTML = modname;
193 modDisplay.style.postion = "relative";
194 modDisplay.title = modinfo.description;
196 let checkbox = modDisplay.appendChild(document.createElement("input"));
197 checkbox.type = "checkbox";
198 checkbox.style.position = "absolute";
199 checkbox.style.right = "5px";
201 checkbox.addEventListener("input", _ => {
202 worldProperties.mods[modname] = checkbox.checked;
205 worldProperties.mods[modname] = checkbox.checked = oldSelectedMods[modname];
210 createWorldGUI.create("h2").innerHTML = " Gamemode";
212 for (let gamemode of ["survival", "creative"]){
213 let radiobox = createWorldGUI.create("input");
214 radiobox.name = "dragonblocks.mainmenu.createWorldGUI.gamemode";
215 radiobox.type = "radio";
216 radiobox.checked = gamemode == worldProperties.gamemode;
217 radiobox.style.position = "relative";
218 radiobox.style.left = "40px";
220 radiobox.addEventListener("input", _ => {
221 if (radiobox.checked)
222 worldProperties.gamemode = gamemode;
225 let label = createWorldGUI.create("label");
226 label.innerHTML = dblib.humanFormat(gamemode);
227 label.style.position = "relative";
228 label.style.left = "40px";
232 createWorldGUI.create("h2").innerHTML = " Mapgen";
234 let selectMapgen = createWorldGUI.create("select");
235 selectMapgen.style.position = "relative";
236 selectMapgen.style.left = "40px";
237 selectMapgen.value = worldProperties.mapgen;
239 selectMapgen.addEventListener("input", _ => {
240 worldProperties.mapgen = selectMapgen.value;
243 for (let mapgen in dragonblocks.mapgen.list)
244 selectMapgen.appendChild(document.createElement("option")).innerHTML = mapgen;
246 createWorldGUI.create("br");
247 createWorldGUI.create("br");
250 createButton = createWorldGUI.create("button");
251 createButton.style.position = "absolute";
252 createButton.style.left = "1%";
253 createButton.style.bottom = "5px";
254 createButton.style.width = "98%";
255 createButton.style.fontSize = "20px";
256 createButton.innerHTML = "Create World";
258 createButton.addEventListener("click", event => {
259 event.srcElement.blur();
260 createWorldGUI.close();
262 dragonblocks.start(worldProperties);
265 createWorldGUI.create("br");
266 createWorldGUI.create("br");
269 worldnameInput.value = "";
270 worldnameAlert.textContent = "";
271 createButton.disabled = dragonblocks.loggedin;
277 text: "Create New World",
279 createWorldGUI.open();
287 let creditsGUI = new dragonblocks.gui.Box();
289 let pages = $.getJSON("credits.json").responseJSON;
292 for (let dir of ["left", "right"]) {
293 let arrow = creditsGUI.create("div");
294 arrow.style.position = "absolute";
295 arrow.style.width = "80px";
296 arrow.style.height = "80px";
297 arrow.style.position = "absolute";
298 arrow.style[dir] = "3px";
299 arrow.style.background = dragonblocks.getTexture("arrow.png");
300 arrow.style.cursor = "pointer";
303 arrow.style.transform = "rotate(180deg)";
305 arrow.addEventListener("click", _ => {
314 dblib.centerVertical(arrow);
317 let creditsContent = creditsGUI.create("center");
319 creditsGUI.addEventListener("open", _ => {
321 page = pages.length - 1;
322 else if (page >= pages.length)
325 creditsContent.innerHTML = pages[page];
326 dragonblocks.resolveTextures(creditsContent);
328 // fix to center the dots of the li elements in chromium as well
330 let lis = creditsContent.getElementsByTagName("li");
333 li.style.width = "max-content";
350 if (dragonblocks.isChromeApp)
358 for (let {text, action, disabled} of buttons) {
359 let button = content.appendChild(document.createElement("button"));
360 button.style.fontSize = "40px";
361 button.style.width = "100%";
362 button.innerHTML = text;
363 button.disabled = disabled;
364 button.addEventListener("click", action);
366 content.appendChild(document.createElement("br"));
367 content.appendChild(document.createElement("br"));
370 for (let [side, text] of [["left", dragonblocks.version.string], ["right", dragonblocks.version.copyright]]) {
371 let notice = content.appendChild(document.createElement("span"));
372 notice.style.position = "fixed";
373 notice.style.bottom = "5px";
374 notice.style[side] = "5px";
375 notice.innerHTML = text;
378 dragonblocks.enterMainMenu = _ => {
379 dragonblocks.loadModList();
380 worlds = dragonblocks.backendCall("getWorlds");
382 content.style.display = "inherit";
383 status.style.display = "none";
385 for (let func of onReload)
389 dragonblocks.registerOnStart(_ => {
390 content.style.display = "none";
391 status.style.display = "inherit";
393 status.innerHTML = "Loading...";
396 dragonblocks.registerOnStarted(_ => {
397 mainmenu.style.visibility = "hidden";
400 dragonblocks.registerOnQuit(_ => {
401 mainmenu.style.visibility = "visible";
402 status.innerHTML = "Saving...";
405 let updateSplash = _ => {
406 splash.style.left = (logo.x + logo.width - splash.clientWidth / 2) + "px";
407 splash.style.top = (logo.y + logo.height / 3 * 2 - splash.clientHeight / 2) + "px";
410 let initMainMenu = _ => {
411 document.body.style.backgroundColor = "skyblue";
412 document.getElementById("elidragon").remove();
413 content.style.width = logo.offsetWidth + "px";
414 mainmenu.style.visibility = "visible";
416 let splashes = $.getJSON("splashes.json").responseJSON;
418 splash.innerHTML = splashes[Math.floor(Math.random() * splashes.length)];
419 let fontSize = Math.min(parseInt(10000 / splash.clientWidth), 30);
420 splash.style.fontSize = fontSize + "px";
425 splash.style.fontSize = Math.sin(counter++ / 100 * Math.PI) * fontSize / 6 + fontSize + "px";
429 dragonblocks.enterMainMenu();
435 logo.addEventListener("load", initMainMenu);