]> git.lizzy.rs Git - dragonblocks.git/blob - engine/init.js
Map abstraction and World class
[dragonblocks.git] / engine / init.js
1 /*
2  * init.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         dragonblocks = {};
25
26         dragonblocks.backendCall = (call, plain, data) => {
27                 data = data || {};
28                 data.call = call;
29
30                 let fetchFunc = plain ? $.get : $.getJSON;
31
32                 let response = fetchFunc({
33                         url: "api.php",
34                         method: "POST",
35                         data: data,
36                 });
37
38                 return plain ? response.responseText : response.responseJSON;
39         };
40
41         dragonblocks.settings = $.getJSON("settings.json").responseJSON;
42
43         let version = dragonblocks.version = $.getJSON("version.json").responseJSON;
44         version.commit = version.development && (dragonblocks.backendCall("commitID", true) || "?");
45         version.string = "Dragonblocks "
46                 + version.major
47                 + "." + version.minor
48                 + (version.patch ? "." + version.patch : "")
49                 + (version.development ? "-dev-" + version.commit : "");
50
51         dragonblocks.isChromeApp = window.chrome && chrome.app;
52
53         addEventListener("error", event => {
54                 if (confirm(event.message + "\nStack trace: \n" + event.error.stack + "\nPlease report this to the dragonblocks developers."))
55                         location.href = version.repo + "/issues/new?"
56                         + "title=" + encodeURIComponent(event.message)
57                         + "&body=" + encodeURIComponent(event.error.stack)
58         });
59
60         dragonblocks.backlog = "";
61
62         dragonblocks.loadModList = _ => {
63                 dragonblocks.gamemods = dragonblocks.backendCall("getGamemods");
64                 dragonblocks.mods = dragonblocks.backendCall("getMods");
65         };
66
67         dragonblocks.loggedin = dragonblocks.backendCall("isLoggedin");
68         dragonblocks.username = dragonblocks.loggedin ? dragonblocks.backendCall("getUsername", true) : "singleplayer";
69
70         dragonblocks.log = text => {
71                 console.log("[Dragonblocks] " + text);
72                 dragonblocks.backlog += text + "\n";
73         };
74
75         dragonblocks.error = err => {
76                 let error = new Error(err);
77                 dragonblocks.backlog += error;
78
79                 throw error;
80         };
81
82         dragonblocks.getToken = _ => {
83                 return "#" + (Math.random() * 10).toString().replace(".", "");
84         };
85
86         dragonblocks.getModInfo = modname => {
87                 return dragonblocks.mods[modname] || dragonblocks.gamemods[modname];
88         };
89
90         dragonblocks.getModpath = modname => {
91                 return dragonblocks.getModInfo(modname).path;
92         };
93
94         let loadingMods = {};
95
96         let loadMod = modname => {
97                 if (loadingMods[modname])
98                         dragonblocks.error("Circular Mod Dependencies: " + modname);
99
100                 if (dragonblocks.loadedMods[modname])
101                         return;
102
103                 let modinfo = dragonblocks.getModInfo(modname);
104
105                 if (! modinfo)
106                         dragonblocks.error("Unresolved Mod Dependencies: " + modname);
107
108                 loadingMods[modname] = true;
109
110                 for (let dependency of modinfo.dependencies)
111                         loadMod(dependency);
112
113                 $.getScript(modinfo.path + "/init.js");
114
115                 dragonblocks.loadedMods[modname] = modinfo;
116                 loadingMods[modname] = false;
117         };
118
119         dragonblocks.loadMods = selectedMods = _ => {
120                 dragonblocks.loadedMods = {};
121
122                 for (let mod in selectedMods)
123                         if (selectedMods[mod])
124                                 loadMod(mod);
125
126                 for (let mod in dragonblocks.gamemods)
127                         loadMod(mod);
128         };
129
130         dragonblocks.start = worldProperties => {
131                 dragonblocks.log("Starting");
132
133                 for (let func of dragonblocks.onStartCallbacks)
134                         func();
135
136                 setTimeout(_ => {
137                         dragonblocks.world = new dragonblocks.World(worldProperties);
138                         dragonblocks.player = dragonblocks.world.player;
139
140                         for (let func of dragonblocks.onStartedCallbacks)
141                                 func();
142                 });
143         };
144
145         dragonblocks.onStartCallbacks = [];
146         dragonblocks.registerOnStart = func => {
147                 dragonblocks.onStartCallbacks.push(func);
148         };
149
150         dragonblocks.onStartedCallbacks = [];
151         dragonblocks.registerOnStarted = func => {
152                 dragonblocks.onStartedCallbacks.push(func);
153         };
154
155         dragonblocks.quit = _ => {
156                 for (let func of dragonblocks.onQuitCallbacks)
157                         func();
158
159                 if (dragonblocks.loggedin)
160                         setTimeout(_ => {
161                                 dragonblocks.player.despawn();
162                                 dragonblocks.world.save();
163                                 location.reload();
164                         });
165                 else
166                         location.reload();
167         };
168
169         dragonblocks.onQuitCallbacks = [];
170         dragonblocks.registerOnQuit = func => {
171                 dragonblocks.onQuitCallbacks.push(func);
172         };
173
174         let modules = [
175                 "assets",
176                 "key_handler",
177                 "gui",
178                 "mapgen",
179                 "world",
180                 "item",
181                 "node",
182                 "tool",
183                 "group",
184                 "builtin",
185                 "map_node",
186                 "map",
187                 "item_stack",
188                 "inventory",
189                 "out_stack",
190                 "inventory_group",
191                 "hudbar",
192                 "inventory_container",
193                 "creative_inventory",
194                 "recipe",
195                 "craftfield",
196                 "menu",
197                 "skin",
198                 "entity",
199                 "map_interaction",
200                 "spawned_entity",
201                 "item_entity",
202                 "falling_node",
203                 "timer",
204                 "player",
205                 "schematic",
206                 "chat",
207                 "chatcommands",
208                 "mainmenu",
209         ];
210
211         let moduleCount = modules.length;
212
213         let status = document.getElementById("elidragon.status");
214         let loadbar = document.getElementById("elidragon.loadbar");
215
216         let loadNextModuleRecursive = _ => {
217                 let nextModule = modules.shift();
218
219                 if (nextModule) {
220                         let filename = nextModule + ".js";
221                         status.innerHTML = filename;
222
223                         $.getScript({
224                                 url: "engine/" + filename,
225                                 async: true,
226                                 cache: false,
227                                 success: _ => {
228                                         loadbar.style.width = (moduleCount - modules.length) / moduleCount * 100 + "%";
229                                         loadNextModuleRecursive();
230                                 },
231                         });
232                 }
233         };
234
235         loadNextModuleRecursive();
236 }