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 splashes = $.getJSON("splashes.json").responseJSON;
45 let status = center.appendChild(document.createElement("h1"));
46 status.style.fontSize = "50px";
47 status.style.display = "none";
49 let content = center.appendChild(document.createElement("div"));
50 content.id = "dragonblocks.mainmenu.content";
51 content.style.position = "relative";
52 content.style.top = "50px";
57 let clearChildren = parent => {
58 while (elem = parent.firstChild)
65 let loadWorldGUI, worldlistDisplay, noWorldsNotice;
67 if (dragonblocks.loggedin) {
70 clearChildren(worldlistDisplay);
72 loadWorldGUI = new dragonblocks.gui.Box();
74 let headline = loadWorldGUI.create("h1");
75 headline.innerHTML = "Select World";
76 headline.align = "center";
78 noWorldsNotice = loadWorldGUI.create("center").appendChild(document.createElement("b"));
80 worldlistDisplay = loadWorldGUI.create("ul");
83 noWorldsNotice.innerHTML = dragonblocks.worlds.length == 0 ? "No Worlds" : "";
85 for (let worldname in dragonblocks.worlds) {
86 let world = dragonblocks.worlds[worldname];
89 let worldDisplay = worldlistDisplay.appendChild(document.createElement("li"));
90 worldDisplay.style.fontSize = "20px";
91 worldDisplay.textContent = world.name;
92 worldDisplay.style.postion = "relative";
94 let button = worldDisplay.appendChild(document.createElement("button"));
95 button.textContent = "Play";
96 button.style.position = "absolute";
97 button.style.right = "5px";
98 button.style.fontSize = "12px";
99 button.addEventListener("click", event => {
100 event.srcElement.blur();
101 loadWorldGUI.close();
103 dragonblocks.worldIsLoaded = true;
104 dragonblocks.worldname = world.name;
105 dragonblocks.world = $.getJSON("worlds/" + worldname + "/world.json").responseJSON;
107 dragonblocks.mods = dragonblocks.world.mods;
109 dragonblocks.start();
117 text: "Load Saved World",
121 disabled: ! dragonblocks.loggedin,
125 // Create World Button
128 let createWorldGUI = new dragonblocks.gui.Box();
131 let worldProperties = {};
133 let headline = createWorldGUI.create("h1");
134 headline.innerHTML = "New World";
135 headline.align = "center";
138 createWorldGUI.create("h2").innerHTML = " World Name";
140 let worldnameInput = createWorldGUI.create("input");
141 worldnameInput.type = "text";
142 worldnameInput.style.position = "relative";
143 worldnameInput.style.left = "40px";
145 let worldnameAlert = createWorldGUI.create("b");
146 worldnameAlert.style.position = "relative";
147 worldnameAlert.style.left = "50px";
149 worldnameInput.addEventListener("input", _ => {
150 let worldname = worldnameInput.value;
152 if(! dragonblocks.loggedin) {
153 worldnameAlert.textContent = "Warning: You are not logged in and cannot save worlds.";
154 worldnameAlert.style.color = "#FF7D00";
155 createButton.disabled = false;
156 } else if (worldname == "") {
157 worldnameAlert.textContent = "";
158 createButton.disabled = true;
159 } else if (! dragonblocks.checkWorldnameSpelling(worldname)) {
160 worldnameAlert.textContent = "The world name contains forbidden characters";
161 worldnameAlert.style.color = "#FF001F";
162 createButton.disabled = true;
163 } else if (dragonblocks.worlds[worldname]) {
164 if (dragonblocks.worlds[worldname].owned) {
165 worldnameAlert.textContent = "Warning: This will overwrite an existing world";
166 worldnameAlert.style.color = "#FF7D00";
167 createButton.disabled = false;
169 worldnameAlert.textContent = "This Worldname is taken";
170 worldnameAlert.style.color = "#FF001F";
171 createButton.disabled = true;
174 worldnameAlert.textContent = "";
175 createButton.disabled = false;
178 worldProperties.worldname = worldname;
182 worldProperties.mods = {};
184 createWorldGUI.create("h2").innerHTML = " Mods";
188 let updateModlist = _ => {
190 clearChildren(modlistDisplay);
192 modlistDisplay = createWorldGUI.create("ul");
194 let oldSelectedMods = worldProperties.mods;
195 worldProperties.mods = {};
197 for (let modname in dragonblocks.mods) {
198 let modinfo = dragonblocks.mods[modname];
200 let modDisplay = modlistDisplay.appendChild(document.createElement("li"));
201 modDisplay.style.fontSize = "20px";
202 modDisplay.innerHTML = mod;
203 modDisplay.style.postion = "relative";
204 modDisplay.title = modinfo.description;
206 let checkbox = modDisplay.appendChild(document.createElement("input"));
207 checkbox.type = "checkbox";
208 checkbox.style.position = "absolute";
209 checkbox.style.right = "5px";
211 checkbox.addEventListener("input", _ => {
212 worldProperties.mods[mod] = checkbox.checked;
215 worldProperties.mods[mod] = checkbox.checked = oldSelectedMods[mod];
220 worldProperties.gamemode = "survival";
222 createWorldGUI.create("h2").innerHTML = " Gamemode";
224 for (let gamemode of ["survival", "creative"]){
225 let radiobox = createWorldGUI.create("input");
226 radiobox.name = "dragonblocks.mainmenu.createWorldGUI.gamemode";
227 radiobox.type = "radio";
228 radiobox.checked = gamemode == worldProperties.gamemode;
229 radiobox.style.position = "relative";
230 radiobox.style.left = "40px";
232 radiobox.addEventListener("input", _ => {
233 if (radiobox.checked)
234 worldProperties.gamemode = gamemode;
237 let label = createWorldGUI.create("label");
238 label.innerHTML = dblib.humanFormat(gamemode);
239 label.style.position = "relative";
240 label.style.left = "40px";
244 createWorldGUI.create("h2").innerHTML = " Mapgen";
246 let selectMapgen = createWorldGUI.create("select");
247 selectMapgen.style.position = "relative";
248 selectMapgen.style.left = "40px";
250 selectMapgen.addEventListener("input", _ => {
251 worldProperties.mapgen = selectMapgen.value;
254 for (let mapgen in dragonblocks.mapgen.list)
255 selectMapgen.appendChild(document.createElement("option")).innerHTML = mapgen;
257 worldProperties.mapgen = selectMapgen.value;
259 createWorldGUI.create("br");
260 createWorldGUI.create("br");
263 createButton = createWorldGUI.create("button");
264 createButton.style.position = "absolute";
265 createButton.style.left = "1%";
266 createButton.style.bottom = "5px";
267 createButton.style.width = "98%";
268 createButton.style.fontSize = "20px";
269 createButton.innerHTML = "Create World";
271 createButton.addEventListener("click", event => {
272 event.srcElement.blur();
273 createWorldGUI.close();
275 dragonblocks.worldIsLoaded = false;
276 dragonblocks.worldname = worldProperties.worldname;
277 dragonblocks.world = dragonblocks.getEmptyWorld();
279 dragonblocks.entities["dragonblocks:player"].meta.creative = (worldProperties.gamemode == "creative");
281 dragonblocks.mapgen.selected = worldProperties.mapgen;
283 dragonblocks.start(worldProperties.mods);
286 createWorldGUI.create("br");
287 createWorldGUI.create("br");
290 worldnameInput.value = "";
291 worldnameAlert.textContent = "";
292 createButton.disabled = dragonblocks.loggedin;
298 text: "Create New World",
300 createWorldGUI.open();
308 let creditsGUI = new dragonblocks.gui.Box();
310 let pages = $.getJSON("credits.json").responseJSON;
313 for (let dir of ["left", "right"]) {
314 let arrow = creditsGUI.create("div");
315 arrow.style.position = "absolute";
316 arrow.style.width = "80px";
317 arrow.style.height = "80px";
318 arrow.style.position = "absolute";
319 arrow.style[dir] = "3px";
320 arrow.style.background = dragonblocks.getTexture("arrow.png");
321 arrow.style.backgroundSize = "cover";
322 arrow.style.cursor = "pointer";
325 arrow.style.transform = "rotate(180deg)";
327 arrow.addEventListener("click", _ => {
336 dblib.centerVertical(arrow);
339 let creditsContent = creditsGUI.create("center");
341 creditsGUI.addEventListener("open", _ => {
343 page = pages.length - 1;
344 else if (page >= pages.length)
347 creditsContent.innerHTML = pages[page];
348 dragonblocks.resolveTextures(creditsContent);
350 // fix to center the dots of the li elements in chromium as well
352 let lis = creditsContent.getElementsByTagName("li");
355 li.style.width = "max-content";
372 if (dragonblocks.isChromeApp)
380 for (let {text, action, disabled} of buttons) {
381 let button = content.appendChild(document.createElement("button"));
382 button.style.fontSize = "40px";
383 button.style.width = "100%";
384 button.innerHTML = text;
385 button.disabled = disabled;
386 button.addEventListener("click", action);
388 content.appendChild(document.createElement("br"));
389 content.appendChild(document.createElement("br"));
392 for (let [side, text] of [["left", dragonblocks.version.string], ["right", dragonblocks.version.copyright]]) {
393 let notice = content.appendChild(document.createElement("span"));
394 notice.style.position = "fixed";
395 notice.style.bottom = "5px";
396 notice.style[side] = "5px";
397 notice.innerHTML = text;
400 dragonblocks.enterMainMenu = _ => {
401 dragonblocks.loadModList();
402 dragonblocks.loadWorldList();
404 content.style.display = "inherit";
405 status.style.display = "none";
407 for (let func of onReload)
411 dragonblocks.registerOnStart(_ => {
412 content.style.display = "none";
413 status.style.display = "inherit";
415 status.innerHTML = "Loading...";
418 dragonblocks.registerOnStarted(_ => {
419 mainmenu.style.visibility = "hidden";
422 dragonblocks.registerOnQuit(_ => {
423 mainmenu.style.visibility = "visible";
424 status.innerHTML = "Saving...";
427 let updateSplash = _ => {
428 splash.style.left = (logo.x + logo.width - splash.clientWidth / 2) + "px";
429 splash.style.top = (logo.y + logo.height / 3 * 2 - splash.clientHeight / 2) + "px";
432 let initMainMenu = _ => {
433 document.body.style.backgroundColor = "skyblue";
434 document.getElementById("elidragon").remove();
435 content.style.width = logo.offsetWidth + "px";
436 mainmenu.style.visibility = "visible";
438 splash.innerHTML = splashes[Math.floor(Math.random() * splashes.length)];
439 let fontSize = Math.min(parseInt(10000 / splash.clientWidth), 30);
440 splash.style.fontSize = fontSize + "px";
445 splash.style.fontSize = Math.sin(counter++ / 100 * Math.PI) * fontSize / 6 + fontSize + "px";
449 dragonblocks.enterMainMenu();
455 logo.addEventListener("load", initMainMenu);