From: Elias Fleckenstein Date: Thu, 1 Jul 2021 13:38:18 +0000 (+0200) Subject: Add Map Manager X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=53039c38bccc528a0fb4bcf1b7e946ce0c64c090;p=dragonblocks.git Add Map Manager - Adds extendible ContentMgr that can be reused later for item definitions - Save multiple maps in world - Fix entity map changing - Fix (non-game) mod loading --- diff --git a/engine/builtin.js b/engine/builtin.js index b33c8d9..f5e011d 100644 --- a/engine/builtin.js +++ b/engine/builtin.js @@ -78,3 +78,16 @@ dragonblocks.registerGroup({ place: "", } }); + +dragonblocks.mapMgr.register("dragonblocks:map", class extends dragonblocks.Map +{ + constructor(data, mapgen) + { + if (data) { + super(data, mapgen); + } else { + super(dragonblocks.settings.map, mapgen); + dragonblocks.mapgen.generate(mapgen, this); + } + } +}); diff --git a/engine/content_mgr.js b/engine/content_mgr.js new file mode 100644 index 0000000..2dc147f --- /dev/null +++ b/engine/content_mgr.js @@ -0,0 +1,81 @@ +/* + * content_mgr.js + * + * Copyright 2021 Elias Fleckenstein + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + * + */ + +dragonblocks.ContentMgr = class +{ + constructor(baseClass) + { + this.baseClass = baseClass; + this.clear(); + } + + register(name, defClass, override) + { + if (! name) + throw new Error("Missing name"); + + if (! name.search(":")) + throw new Error("Non-namespaced name"); + + if (! defClass) + throw new Error("Missing definition class"); + + if (! (defClass.prototype instanceof this.baseClass)) + throw new Error("Definition class does not extend base class"); + + let oldDef = this.getDef(name); + + if (oldDef && ! override) + throw new Error("Already registered"); + + if (! oldDef && override) + throw new Error("Not registered"); + + this.defs[name] = defClass; + } + + override(name, def) + { + this.register(name, def, true); + } + + getDef(name) + { + return this.defs[name]; + } + + create(name, ...args) + { + let defClass = this.getDef(name); + + if (! defClass) + throw new Error("Not defined"); + + return new defClass(...args); + } + + clear() + { + this.defs = {}; + } +}; diff --git a/engine/init.js b/engine/init.js index e8daae4..f07d3ae 100644 --- a/engine/init.js +++ b/engine/init.js @@ -112,7 +112,7 @@ loadingMods[modname] = false; }; - dragonblocks.loadMods = selectedMods = _ => { + dragonblocks.loadMods = selectedMods => { dragonblocks.loadedMods = {}; for (let mod in selectedMods) @@ -168,6 +168,7 @@ }; let modules = [ + "content_mgr", "assets", "key_handler", "gui", @@ -177,10 +178,10 @@ "node", "tool", "group", - "builtin", "map_node", "map_display", "map", + "builtin", "item_stack", "inventory", "out_stack", diff --git a/engine/mainmenu.js b/engine/mainmenu.js index a525c0a..dc57414 100644 --- a/engine/mainmenu.js +++ b/engine/mainmenu.js @@ -176,13 +176,10 @@ // Mods createWorldGUI.create("h2").innerHTML = " Mods"; - let modlistDisplay; + let modlistDisplay = createWorldGUI.create("ul"); let updateModlist = _ => { - if (modlistDisplay) - clearChildren(modlistDisplay); - else - modlistDisplay = createWorldGUI.create("ul"); + clearChildren(modlistDisplay); let oldSelectedMods = worldProperties.mods; worldProperties.mods = {}; @@ -192,7 +189,7 @@ let modDisplay = modlistDisplay.appendChild(document.createElement("li")); modDisplay.style.fontSize = "20px"; - modDisplay.innerHTML = mod; + modDisplay.innerHTML = modname; modDisplay.style.postion = "relative"; modDisplay.title = modinfo.description; @@ -202,10 +199,10 @@ checkbox.style.right = "5px"; checkbox.addEventListener("input", _ => { - worldProperties.mods[mod] = checkbox.checked; + worldProperties.mods[modname] = checkbox.checked; }); - worldProperties.mods[mod] = checkbox.checked = oldSelectedMods[mod]; + worldProperties.mods[modname] = checkbox.checked = oldSelectedMods[modname]; } }; diff --git a/engine/map.js b/engine/map.js index db4211a..7dff2bc 100644 --- a/engine/map.js +++ b/engine/map.js @@ -31,10 +31,7 @@ dragonblocks.Map = class this.entityContainer.style.position = "absolute"; this.entityContainer.style.visibility = "hidden"; - if (data) - this.deserialize(data); - else - this.clear(); + this.deserialize(data); } serialize() @@ -43,8 +40,6 @@ dragonblocks.Map = class data: this.data, width: this.width, height: this.height, - displayLeft: this.displayLeft, - displayTop: this.displayTop, structures: this.structures, entities: dblib.removeTmp(this.entities), }; @@ -53,21 +48,22 @@ dragonblocks.Map = class deserialize(data) { this.data = []; + this.width = data.width; this.height = data.height; - this.displayLeft = data.displayLeft; - this.displayTop = data.displayTop; + this.entities = []; - this.structures = data.structures; + this.structures = data.structures || {}; for (let x = 0; x < this.width; x++) { this.data[x] = []; for (let y = 0; y < this.height; y++) - this.setNode(x, y, new dragonblocks.MapNode().createFromMapNode(data.data[x][y])); + this.setNode(x, y, data.data ? new dragonblocks.MapNode().createFromMapNode(data.data[x][y]) : new dragonblocks.MapNode("air")); } - for (let entity of data.entities) - new dragonblocks.SpawnedEntity(entity); + if (data.entities) + for (let entity of data.entities) + new dragonblocks.SpawnedEntity(entity, this); } setActive() @@ -82,23 +78,6 @@ dragonblocks.Map = class this.entityContainer.style.visibility = "hidden"; } - clear() - { - this.data = []; - this.width = dragonblocks.settings.map.width; - this.height = dragonblocks.settings.map.height; - this.displayTop = dragonblocks.settings.map.height / 2; - this.displayLeft = dragonblocks.settings.map.width / 2 - 5; - this.entities = []; - this.structures = {}; - - for (let x = 0; x < this.width; x++) { - this.data[x] = []; - for (let y = 0; y < this.height; y++) - this.setNode(x, y, new dragonblocks.MapNode("air")); - } - } - withinBounds(x, y) { return x < this.width && y < this.height && x >= 0 && y >= 0; @@ -162,6 +141,8 @@ dragonblocks.Map = class }; +dragonblocks.mapMgr = new dragonblocks.ContentMgr(dragonblocks.Map); + dragonblocks.onActivateCallbacks = []; dragonblocks.registerOnActivate = func => { dragonblocks.onActivateCallbacks.push(func); diff --git a/engine/map_display.js b/engine/map_display.js index 58c64ff..5e72d9e 100644 --- a/engine/map_display.js +++ b/engine/map_display.js @@ -97,9 +97,9 @@ dragonblocks.MapDisplay = class this.autoScroll(); } - setSkyColor(color) + setSky(sky) { - this.element.style.backgroundColor = color; + this.element.style.background = sky; } getActiveEntityContainer() @@ -190,8 +190,8 @@ dragonblocks.registerOnQuit(_ => { }); dragonblocks.registerOnStarted(_ => { - dragonblocks.mapDisplay.setSkyColor("skyblue"); - dragonblocks.mapDisplay.setMap(dragonblocks.world.map); + dragonblocks.mapDisplay.setSky("skyblue"); + dragonblocks.mapDisplay.setMap(dragonblocks.player.map); dragonblocks.mapDisplay.setAnchor(dragonblocks.player); dragonblocks.mapDisplay.setActive(); diff --git a/engine/spawned_entity.js b/engine/spawned_entity.js index bdc5153..56b8903 100644 --- a/engine/spawned_entity.js +++ b/engine/spawned_entity.js @@ -86,7 +86,7 @@ dragonblocks.SpawnedEntity = class map.entities.push(this); this.tmp.map = map; - this.tmp.display = map.entityContainer.appendChild(this.display); + this.tmp.display = map.entityContainer.appendChild(this.tmp.display); this.teleport(x, y); } diff --git a/engine/world.js b/engine/world.js index 2579788..689d3b6 100644 --- a/engine/world.js +++ b/engine/world.js @@ -32,35 +32,42 @@ dragonblocks.World = class this.load(); } else { this.mods = properties.mods; - this.loadMods(); - this.map = new dragonblocks.Map(); + this.maps = {}; + this.mapgen = properties.mapgen; + this.loadMaps({}); - this.player = new dragonblocks.Player(null, this.map); + this.player = new dragonblocks.Player(null, this.maps["dragonblocks:map"]); this.player.setGamemode(properties.gamemode); - - dragonblocks.mapgen.generate(properties.mapgen, this.map); } } serialize() { - return { + let data = { mods: this.mods, - map: this.map.serialize(), player: this.player.serialize(), + maps: {}, + mapgen: this.mapgen, }; + + for (let name in this.maps) + data.maps[name] = this.maps[name].serialize(); + + return data; } deserialize(data) { this.mods = data.mods; - this.loadMods(); - this.map = new dragonblocks.Map(data.map); - this.player = new dragonblocks.Player(data.player, this.map); + this.maps = {}; + this.mapgen = data.mapgen; + this.loadMaps(data.maps); + + this.player = new dragonblocks.Player(data.player, this.maps["dragonblocks:map"]); } save() @@ -78,6 +85,12 @@ dragonblocks.World = class { dragonblocks.loadMods(this.mods); } + + loadMaps(data) + { + for (let name in dragonblocks.mapMgr.defs) + this.maps[name] = dragonblocks.mapMgr.create(name, data[name], this.mapgen); + } }; dragonblocks.World.Properties = class