]> git.lizzy.rs Git - dragonblocks.git/blob - engine/map.js
Abstract MapDisplay from Map
[dragonblocks.git] / engine / map.js
1 /*
2  * map.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.Map = class
25 {
26         constructor(data)
27         {
28                 this.active = false;
29
30                 this.entityContainer = dragonblocks.mapDisplay.element.appendChild(document.createElement("div"));
31                 this.entityContainer.style.position = "absolute";
32                 this.entityContainer.style.visibility = "hidden";
33
34                 if (data)
35                         this.deserialize(data);
36                 else
37                         this.clear();
38         }
39
40         serialize()
41         {
42                 return {
43                         data: this.data,
44                         width: this.width,
45                         height: this.height,
46                         displayLeft: this.displayLeft,
47                         displayTop: this.displayTop,
48                         structures: this.structures,
49                         entities: dblib.removeTmp(this.entities),
50                 };
51         }
52
53         deserialize(data)
54         {
55                 this.data = [];
56                 this.width = data.width;
57                 this.height = data.height;
58                 this.displayLeft = data.displayLeft;
59                 this.displayTop = data.displayTop;
60                 this.entities = [];
61                 this.structures = data.structures;
62
63                 for (let x = 0; x < this.width; x++) {
64                         this.data[x] = [];
65                         for (let y = 0; y < this.height; y++)
66                                 this.setNode(x, y, new dragonblocks.MapNode().createFromMapNode(data.data[x][y]));
67                 }
68
69                 for (let entity of data.entities)
70                         new dragonblocks.SpawnedEntity(entity);
71         }
72
73         setActive()
74         {
75                 this.active = true;
76                 this.entityContainer.style.visibility = "inherit";
77         }
78
79         setInactive()
80         {
81                 this.active = false;
82                 this.entityContainer.style.visibility = "hidden";
83         }
84
85         clear()
86         {
87                 this.data = [];
88                 this.width = dragonblocks.settings.map.width;
89                 this.height = dragonblocks.settings.map.height;
90                 this.displayTop = dragonblocks.settings.map.height / 2;
91                 this.displayLeft = dragonblocks.settings.map.width / 2 - 5;
92                 this.entities = [];
93                 this.structures = {};
94
95                 for (let x = 0; x < this.width; x++) {
96                         this.data[x] = [];
97                         for (let y = 0; y < this.height; y++)
98                                 this.setNode(x, y, new dragonblocks.MapNode("air"));
99                 }
100         }
101
102         withinBounds(x, y)
103         {
104                 return x < this.width && y < this.height && x >= 0 && y >= 0;
105         }
106
107         getNode(x, y)
108         {
109                 if (this.withinBounds(x, y))
110                         return this.data[x][y];
111         }
112
113         setNode(x, y, node)
114         {
115                 node = new dragonblocks.MapNode(node);
116
117                 if (this.withinBounds(x, y)) {
118                         let oldNode = this.data[x][y];
119                         let oldNodeDef = oldNode instanceof dragonblocks.MapNode && oldNode.toNode();
120                         oldNodeDef && oldNodeDef.onremove && oldNodeDef.onremove(this, x, y);
121
122                         this.data[x][y] = node;
123
124                         let nodeDef = node.toNode();
125                         nodeDef.onset && nodeDef.onset(this, x, y);
126
127                         this.active && dragonblocks.mapDisplay.updateNode(x, y);
128                 }
129         }
130
131         activate(x, y)
132         {
133                 for (let ix = x - 1; ix <= x + 1; ix++) {
134                         for (let iy = y - 1; iy <= y + 1; iy++) {
135                                 let node = this.getNode(ix, iy);
136
137                                 if (! node)
138                                         continue;
139
140                                 let nodeDef = node.toNode();
141                                 nodeDef.onactivate && nodeDef.onactivate(this, ix, iy);
142
143                                 for (let func of dragonblocks.onActivateCallbacks)
144                                         func(this, ix, iy);
145                         }
146                 }
147         }
148
149         addStructure(name, msg, pos)
150         {
151                 this.structures[name] = this.structures[name] || [];
152                 this.structures[name].push({msg, pos});
153         }
154
155         spawnEntity(name, x, y)
156         {
157                 let def = dragonblocks.entities[name];
158
159                 if (def)
160                         return new dragonblocks.SpawnedEntity(def, this, x, y);
161         }
162
163 };
164
165 dragonblocks.onActivateCallbacks = [];
166 dragonblocks.registerOnActivate = func => {
167         dragonblocks.onActivateCallbacks.push(func);
168 };