]> git.lizzy.rs Git - dragonblocks.git/blob - engine/player.js
Abstract MapDisplay from Map
[dragonblocks.git] / engine / player.js
1 /*
2  * player.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 dragonblocks.registerTool({
24         name: "dragonblocks:hand",
25         interval: 500,
26         groups: [
27                 {
28                         name: "default",
29                         damage: 2,
30                 },
31                 {
32                         name: "cracky",
33                         damage: 0,
34                 }
35         ]
36 });
37 dragonblocks.registerTool({
38         name: "dragonblocks:creative_hand",
39         range: Infinity,
40         groups: [
41                 {
42                         name: "default",
43                         damage: Infinity
44                 }
45         ]
46 });
47 dragonblocks.registerEntity({
48         name: "dragonblocks:player",
49         gravity: true,
50         width: 1,
51         height: 2,
52         horizontalSpeed: dragonblocks.settings.player.speed,
53         verticalSpeed: dragonblocks.settings.player.jumpspeed,
54         meta: {
55                 skin: dragonblocks.settings.player.defaultSkin,
56                 creative: false,
57         }
58 });
59
60 dragonblocks.Player = class extends dragonblocks.SpawnedEntity
61 {
62         constructor(data, map)
63         {
64                 if (data)
65                         super(data, map);
66                 else
67                         super(dragonblocks.entities["dragonblocks:player"], map, map.width / 2, 5);
68
69                 let self = this;
70
71                 // Skin
72                 this.skin = this.meta.skin;
73
74                 // Inventory
75                 this.tmp.inventory = new dragonblocks.InventoryGroup();                                                                 // Create inventory group that can hold multiple inventories
76
77                 // Main Inventory
78                 this.tmp.mainInventory = new dragonblocks.Inventory(32, 8);                                                             // The main Inventory
79
80                 if (this.meta.mainInventory)
81                         this.tmp.mainInventory.deserialize(this.meta.mainInventory);                                            // Load saved Inventory
82
83                 this.tmp.mainInventory.addEventListener("updateStack", event => {
84                         self.meta.mainInventory = this.tmp.mainInventory.serialize();                                           // Save inventory after every change
85
86                         if (self.gamemode == "creative" && event.stack.count > 1)                                                       // Keep count of every stack at one when in creative
87                                 event.stack.count = 1;
88                 });
89
90                 this.tmp.mainInventory.addEventListener("updateStack", _ => {
91                         if (self.tmp.hudbar)
92                                 self.tmp.hudbar.update();
93                 });
94
95                 // Hudbar
96                 this.tmp.hudbar = new dragonblocks.Hudbar(this.tmp.mainInventory, 8);                                   // The hudbar has 8 slots
97
98                 // Creative Inventory
99                 let creativelist = [];
100
101                 dragonblocks.registeredItems.filter(item => {
102                         return ! item.hidden;
103                 }).forEach(item => {
104                         creativelist.push(item.name);
105                 });
106
107                 this.tmp.creativeInventory = new dragonblocks.CreativeInventory(32, creativelist, 8);   // The creative Inventory contains every registered item that is not marked as hidden
108
109                 // Survival Inventory
110                 this.tmp.survivalInventory = new dragonblocks.InventoryContainer({
111                         inventory: new dragonblocks.Craftfield(3, 3),
112                         top: 0.5,
113                         bottom: 0.5,
114                         left: 1,
115                         right: 2,
116                 });
117
118                 if (this.meta.survivalInventory)
119                         this.tmp.survivalInventory.deserialize(this.meta.survivalInventory);
120
121                 this.tmp.survivalInventory.addEventListener("updateStack", _ => {
122                         self.meta.survivalInventory = this.tmp.survivalInventory.serialize();
123                 });
124
125                 // Init Inventory
126                 this.resetInventoryElements();
127
128                 // Map Interaction
129                 this.tmp.tool = null;
130                 this.tmp.defaultTool = dragonblocks.tools[this.meta.creative ? "dragonblocks:creative_hand" : "dragonblocks:hand"];
131                 this.initMapInteraction();
132
133                 // Controls
134                 dragonblocks.keyHandler.down(" ", _ => {
135                         self.jump();
136                 });
137
138                 dragonblocks.keyHandler.up(" ", _ => {
139                         self.stopJump();
140                 });
141
142                 dragonblocks.keyHandler.down("w", _ => {
143                         self.jump();
144                 });
145
146                 dragonblocks.keyHandler.up("w", _ => {
147                         self.stopJump();
148                 });
149
150                 dragonblocks.keyHandler.down("ArrowLeft", _ => {
151                         self.moveLeft();
152                 });
153
154                 dragonblocks.keyHandler.down("ArrowRight", _ => {
155                         self.moveRight();
156                 });
157
158                 dragonblocks.keyHandler.down("a", _ => {
159                         self.moveLeft();
160                 });
161
162                 dragonblocks.keyHandler.down("d", _ => {
163                         self.moveRight();
164                 });
165
166                 dragonblocks.keyHandler.up("ArrowLeft", _ => {
167                         self.stop();
168                 });
169
170                 dragonblocks.keyHandler.up("ArrowRight", _ => {
171                         self.stop();
172                 });
173
174                 dragonblocks.keyHandler.up("a", _ => {
175                         self.stop();
176                 });
177
178                 dragonblocks.keyHandler.up("d", _ => {
179                         self.stop();
180                 });
181
182                 dragonblocks.keyHandler.down("i", _ => {
183                         self.toggleInventory();
184                 });
185
186                 dragonblocks.keyHandler.down("n", _ => {
187                         self.nextItem();
188                 });
189
190                 dragonblocks.keyHandler.down("b", _=> {
191                         self.previousItem();
192                 });
193
194                 dragonblocks.keyHandler.down("scroll", _ => {
195                         self.nextItem();
196                 });
197
198                 dragonblocks.keyHandler.up("scroll", _=>{
199                         self.previousItem();
200                 });
201
202                 for (let i = 1; i < 9; i++) {
203                         dragonblocks.keyHandler.down(i.toString(), _ => {
204                                 self.select(i - 1);
205                         });
206                 }
207
208                 addEventListener("mouseup", event => {
209                         if (event.which == 1)
210                                 self.digStop();
211                 });
212
213                 addEventListener("keydown", event => {
214                         if (event.key == "Escape" && self.inventoryIsOpen())
215                                 self.closeInventory();
216                 });
217
218                 // Map Interaction Controls
219                 for (let x = 0; x < dragonblocks.mapDisplay.width; x++) {
220                         for (let y = 0; y < dragonblocks.mapDisplay.height; y++) {
221                                 let nodeDisplay = dragonblocks.mapDisplay.getNode(x, y);
222
223                                 nodeDisplay.addEventListener("mouseover", event => {
224                                         if (self.canReach(x + dragonblocks.mapDisplay.left, y + dragonblocks.mapDisplay.top))
225                                                 event.srcElement.style.boxShadow = "0 0 0 1px black inset";
226                                 });
227
228                                 nodeDisplay.addEventListener("mouseleave", event => {
229                                         event.srcElement.style.boxShadow = "none";
230                                 });
231
232                                 nodeDisplay.addEventListener("mousedown", event => {
233                                         let [ix, iy] = [x + dragonblocks.mapDisplay.left, y + dragonblocks.mapDisplay.top];
234
235                                         switch(event.which) {
236                                                 case 1:
237                                                         self.digStart(ix, iy);
238                                                         break;
239
240                                                 case 3:
241                                                         self.build(ix, iy);
242                                                         break;
243                                         };
244                                 });
245                         }
246                 }
247         }
248
249         serialize()
250         {
251                 return dblib.removeTmp([this])[0];
252         }
253
254         setMap(map, x, y)
255         {
256                 super.setMap(map, x, y);
257                 this.updateMapInteractionMap();
258                 dragonblocks.mapDisplay.setMap(map);
259         }
260
261         set skin(value)
262         {
263                 this.meta.skin = value;
264                 this.texture = dragonblocks.registeredSkins[value].texture;
265                 this.updateTexture();
266         }
267
268         get skin()
269         {
270                 return this.meta.skin;
271         }
272
273         set gamemode(mode)
274         {
275                 this.setGamemode(mode);
276         }
277
278         get gamemode()
279         {
280                 return this.meta.creative ? "creative" : "survival";
281         }
282
283         get tool()
284         {
285                 return dragonblocks.tools[this.getWieldedItem().item] || this.tmp.defaultTool;
286         }
287
288         setGamemode(mode)
289         {
290                 switch (mode.toString().toLowerCase()) {
291                         case "0":
292                         case "survival":
293                                 this.meta.creative = false;
294                                 break;
295
296                         case "1":
297                         case "creative":
298                                 this.meta.creative = true;
299                                 break;
300
301                         default:
302                                 return false;
303                 }
304
305                 this.resetInventoryElements();
306                 this.tmp.defaultTool = dragonblocks.tools[this.meta.creative ? "dragonblocks:creative_hand" : "dragonblocks:hand"];
307
308                 return true;
309         }
310
311         inventoryIsOpen()
312         {
313                 return this.tmp.inventory.opened;
314         }
315
316         openInventory()
317         {
318                 this.tmp.inventory.open();
319                 dragonblocks.keyHandler.lockAll();
320                 dragonblocks.keyHandler.unlock("i");
321                 dragonblocks.gui.showLayer();
322         }
323
324         closeInventory()
325         {
326                 this.tmp.inventory.close();
327                 dragonblocks.keyHandler.unlockAll();
328                 dragonblocks.gui.hideLayer();
329         }
330
331         toggleInventory()
332         {
333                 this.inventoryIsOpen() ? this.closeInventory() : this.openInventory();
334         }
335
336         give(itemstring)
337         {
338                 return this.tmp.mainInventory.add(itemstring);
339         }
340
341         clearInventory()
342         {
343                 this.tmp.mainInventory.clear();
344         }
345
346         setInventoryElements(elems)
347         {
348                 this.tmp.inventory.elements = elems;
349         }
350
351         resetInventoryElements()
352         {
353                 let elems = [this.tmp.mainInventory];
354                 elems.unshift(this.gamemode == "creative" ? this.tmp.creativeInventory : this.tmp.survivalInventory);
355                 this.setInventoryElements(elems);
356         }
357
358         previousItem()
359         {
360                 this.tmp.hudbar.previousItem();
361         }
362
363         nextItem()
364         {
365                 this.tmp.hudbar.nextItem();
366         }
367
368         select(i)
369         {
370                 this.tmp.hudbar.select(i);
371         }
372
373         getWieldedItem()
374         {
375                 return this.tmp.hudbar.getSelectedItem();
376         }
377
378         set onNextInventoryClose(func)
379         {
380                 this.tmp.inventory.onNextClose = func;
381         }
382 };
383
384 Object.assign(dragonblocks.Player.prototype, dragonblocks.MapInteraction);      // Mixin