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,
24 dragonblocks.Map = class
29 this.deserialize(data);
34 this.updateGraphics();
43 displayLeft: this.displayLeft,
44 displayTop: this.displayTop,
45 structures: this.structures,
46 entities: dblib.removeTmp(this.entities),
53 this.width = data.width;
54 this.height = data.height;
55 this.displayLeft = data.displayLeft;
56 this.displayTop = data.displayTop;
58 this.structures = data.structures;
60 for (let x = 0; x < this.width; x++) {
62 for (let y = 0; y < this.height; y++)
63 this.setNode(x, y, new dragonblocks.MapNode().createFromMapNode(data.data[x][y]));
66 for (let entity of data.entities)
67 new dragonblocks.SpawnedEntity(entity);
73 this.width = dragonblocks.settings.map.width;
74 this.height = dragonblocks.settings.map.height;
75 this.displayTop = dragonblocks.settings.map.height / 2;
76 this.displayLeft = dragonblocks.settings.map.width / 2 - 5;
80 for (let x = 0; x < this.width; x++) {
82 for (let y = 0; y < this.height; y++)
83 this.setNode(x, y, new dragonblocks.MapNode("air"));
89 return x < this.width && y < this.height && x >= 0 && y >= 0;
94 if (this.withinBounds(x, y))
95 return this.data[x][y];
100 node = new dragonblocks.MapNode(node);
102 if (this.withinBounds(x, y)) {
103 let oldNode = this.data[x][y];
104 let oldNodeDef = oldNode instanceof dragonblocks.MapNode && oldNode.toNode();
105 oldNodeDef && oldNodeDef.onremove && oldNodeDef.onremove(this, x, y);
107 this.data[x][y] = node;
109 let nodeDef = node.toNode();
110 nodeDef.onset && nodeDef.onset(this, x, y);
112 this.updateNodeGraphics(x, y);
118 for (let ix = x - 1; ix <= x + 1; ix++) {
119 for (let iy = y - 1; iy <= y + 1; iy++) {
120 let node = this.getNode(ix, iy);
125 let nodeDef = node.toNode();
126 nodeDef.onactivate && nodeDef.onactivate(this, ix, iy);
128 for (let func of dragonblocks.onActivateCallbacks)
136 return document.getElementById("dragonblocks.map.node[" + (x - this.displayLeft) + "][" + (y - this.displayTop) + "]");
139 getScreenCoordinates(x, y)
141 return [Math.floor(x / dragonblocks.settings.map.scale) + this.displayLeft, Math.floor(y / dragonblocks.settings.map.scale) + this.displayTop];
144 updateNodeGraphics(x, y)
146 let nodeDisplay = this.getNodeDisplay(x, y);
151 let nodeDef = this.getNode(x, y).toNode();
156 nodeDisplay.style.background = dragonblocks.getTexture(nodeDef.texture);
157 nodeDisplay.style.backgroundSize = "cover";
158 nodeDisplay.style.zIndex = nodeDef.zIndex || "1";
163 if (this.displayLeft < 0)
164 this.displayLeft = 0;
165 else if (this.displayLeft + this.displayWidth > this.width)
166 this.displayLeft = this.width - this.displayWidth;
168 if (this.displayTop < 0)
170 else if (this.displayTop + this.displayHeight > this.height)
171 this.displayTop = this.height - this.displayHeight;
173 for (let x = 0; x < this.displayWidth; x++) {
174 for(let y = 0; y < this.displayHeight; y++) {
175 this.updateNodeGraphics(x + this.displayLeft, y + this.displayTop);
182 this.displayWidth = Math.min(Math.ceil(innerWidth / dragonblocks.settings.map.scale), this.width);
183 this.displayHeight = Math.min(Math.ceil(innerHeight / dragonblocks.settings.map.scale), this.height);
185 let display = document.body.insertBefore(document.createElement("div"), document.body.firstChild);
186 display.id = "dragonblocks.map";
187 display.style.width = this.displayWidth * dragonblocks.settings.map.scale + "px";
188 display.style.height = this.displayHeight * dragonblocks.settings.map.scale + "px";
189 display.style.position = "fixed";
190 display.style.top = "0px";
191 display.style.left = "0px";
192 display.style.backgroundColor = "skyblue";
193 display.style.visibility = "hidden";
195 for (let x = 0; x < this.displayWidth; x++){
196 for (let y = 0; y < this.displayHeight; y++){
197 let nodeDisplay = display.appendChild(document.createElement("div"));
198 nodeDisplay.id = "dragonblocks.map.node[" + x + "][" + y + "]";
199 nodeDisplay.style.position = "absolute";
200 nodeDisplay.style.top = y * dragonblocks.settings.map.scale + "px";
201 nodeDisplay.style.left = x * dragonblocks.settings.map.scale + "px";
202 nodeDisplay.style.width = dragonblocks.settings.map.scale + "px";
203 nodeDisplay.style.height = dragonblocks.settings.map.scale + "px";
208 addStructure(name, msg, pos)
210 this.structures[name] = this.structures[name] || [];
211 this.structures[name].push({msg, pos});
214 spawnEntity(name, x, y)
216 let def = dragonblocks.entities[name];
219 return new dragonblocks.SpawnedEntity(def, this, x, y);
224 dragonblocks.onActivateCallbacks = [];
225 dragonblocks.registerOnActivate = func => {
226 dragonblocks.onActivateCallbacks.push(func);
229 dragonblocks.registerOnStarted(_ => {
230 document.getElementById("dragonblocks.map").style.visibility = "visible";
233 dragonblocks.registerOnQuit(_ => {
234 document.getElementById("dragonblocks.map").style.visibility = "hidden";