]> git.lizzy.rs Git - dragonblocks.git/blob - engine/player.js
4a8d1d1c210f60fc25f90bb15e2b1a283625fd0a
[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                 // Map Scroll
134                 setInterval(_ => {
135                         if (map.displayLeft + map.displayWidth < self.x + self.width + 3)
136                                 map.displayLeft = parseInt(self.x + self.width + 3 - map.displayWidth);
137                         else if (map.displayLeft > self.x - 2)
138                                 map.displayLeft = parseInt(self.x - 2);
139
140                         if (map.displayTop + map.displayHeight < self.y + self.height + 3)
141                                 map.displayTop = parseInt(self.y + self.height + 3 - map.displayHeight);
142                         else if (map.displayTop > self.y - 2)
143                                 map.displayTop = parseInt(self.y - 2);
144
145                         map.updateGraphics();
146                 });
147
148                 // Controls
149                 dragonblocks.keyHandler.down(" ", _ => {
150                         self.jump();
151                 });
152
153                 dragonblocks.keyHandler.up(" ", _ => {
154                         self.stopJump();
155                 });
156
157                 dragonblocks.keyHandler.down("w", _ => {
158                         self.jump();
159                 });
160
161                 dragonblocks.keyHandler.up("w", _ => {
162                         self.stopJump();
163                 });
164
165                 dragonblocks.keyHandler.down("ArrowLeft", _ => {
166                         self.moveLeft();
167                 });
168
169                 dragonblocks.keyHandler.down("ArrowRight", _ => {
170                         self.moveRight();
171                 });
172
173                 dragonblocks.keyHandler.down("a", _ => {
174                         self.moveLeft();
175                 });
176
177                 dragonblocks.keyHandler.down("d", _ => {
178                         self.moveRight();
179                 });
180
181                 dragonblocks.keyHandler.up("ArrowLeft", _ => {
182                         self.stop();
183                 });
184
185                 dragonblocks.keyHandler.up("ArrowRight", _ => {
186                         self.stop();
187                 });
188
189                 dragonblocks.keyHandler.up("a", _ => {
190                         self.stop();
191                 });
192
193                 dragonblocks.keyHandler.up("d", _ => {
194                         self.stop();
195                 });
196
197                 dragonblocks.keyHandler.down("i", _ => {
198                         self.toggleInventory();
199                 });
200
201                 dragonblocks.keyHandler.down("n", _ => {
202                         self.nextItem();
203                 });
204
205                 dragonblocks.keyHandler.down("b", _=> {
206                         self.previousItem();
207                 });
208
209                 dragonblocks.keyHandler.down("scroll", _ => {
210                         self.nextItem();
211                 });
212
213                 dragonblocks.keyHandler.up("scroll", _=>{
214                         self.previousItem();
215                 });
216
217                 for (let i = 1; i < 9; i++) {
218                         dragonblocks.keyHandler.down(i.toString(), _ => {
219                                 self.select(i - 1);
220                         });
221                 }
222
223                 addEventListener("mouseup", event => {
224                         if (event.which == 1)
225                                 self.digStop();
226                 });
227
228                 addEventListener("keydown", event => {
229                         if (event.key == "Escape" && self.inventoryIsOpen())
230                                 self.closeInventory();
231                 });
232
233                 // Map Interaction Controls
234                 for (let x = 0; x < map.displayWidth; x++) {
235                         for (let y = 0; y < map.displayHeight; y++) {
236                                 let nodeDisplay = document.getElementById("dragonblocks.map.node[" + x + "][" + y + "]");
237
238                                 nodeDisplay.addEventListener("mouseover", event => {
239                                         if (self.canReach(x + map.displayLeft, y + map.displayTop))
240                                                 event.srcElement.style.boxShadow = "0 0 0 1px black inset";
241                                 });
242
243                                 nodeDisplay.addEventListener("mouseleave", event => {
244                                         event.srcElement.style.boxShadow = "none";
245                                 });
246
247                                 nodeDisplay.addEventListener("mousedown", event => {
248                                         let [ix, iy] = [x + map.displayLeft, y + map.displayTop];
249
250                                         switch(event.which) {
251                                                 case 1:
252                                                         self.digStart(ix, iy);
253                                                         break;
254
255                                                 case 3:
256                                                         self.build(ix, iy);
257                                                         break;
258                                         };
259                                 });
260                         }
261                 }
262         }
263
264         serialize()
265         {
266                 return dblib.removeTmp([this])[0];
267         }
268
269         set skin(value)
270         {
271                 this.meta.skin = value;
272                 this.texture = dragonblocks.registeredSkins[value].texture;
273                 this.updateTexture();
274         }
275
276         get skin()
277         {
278                 return this.meta.skin;
279         }
280
281         set gamemode(mode)
282         {
283                 this.setGamemode(mode);
284         }
285
286         get gamemode()
287         {
288                 return this.meta.creative ? "creative" : "survival";
289         }
290
291         get tool()
292         {
293                 return dragonblocks.tools[this.getWieldedItem().item] || this.tmp.defaultTool;
294         }
295
296         setGamemode(mode)
297         {
298                 switch (mode.toString().toLowerCase()) {
299                         case "0":
300                         case "survival":
301                                 this.meta.creative = false;
302                                 break;
303
304                         case "1":
305                         case "creative":
306                                 this.meta.creative = true;
307                                 break;
308
309                         default:
310                                 return false;
311                 }
312
313                 this.resetInventoryElements();
314                 this.tmp.defaultTool = dragonblocks.tools[this.meta.creative ? "dragonblocks:creative_hand" : "dragonblocks:hand"];
315
316                 return true;
317         }
318
319         inventoryIsOpen()
320         {
321                 return this.tmp.inventory.opened;
322         }
323
324         openInventory()
325         {
326                 this.tmp.inventory.open();
327                 dragonblocks.keyHandler.lockAll();
328                 dragonblocks.keyHandler.unlock("i");
329                 dragonblocks.gui.showLayer();
330         }
331
332         closeInventory()
333         {
334                 this.tmp.inventory.close();
335                 dragonblocks.keyHandler.unlockAll();
336                 dragonblocks.gui.hideLayer();
337         }
338
339         toggleInventory()
340         {
341                 this.inventoryIsOpen() ? this.closeInventory() : this.openInventory();
342         }
343
344         give(itemstring)
345         {
346                 return this.tmp.mainInventory.add(itemstring);
347         }
348
349         clearInventory()
350         {
351                 this.tmp.mainInventory.clear();
352         }
353
354         setInventoryElements(elems)
355         {
356                 this.tmp.inventory.elements = elems;
357         }
358
359         resetInventoryElements()
360         {
361                 let elems = [this.tmp.mainInventory];
362                 elems.unshift(this.gamemode == "creative" ? this.tmp.creativeInventory : this.tmp.survivalInventory);
363                 this.setInventoryElements(elems);
364         }
365
366         previousItem()
367         {
368                 this.tmp.hudbar.previousItem();
369         }
370
371         nextItem()
372         {
373                 this.tmp.hudbar.nextItem();
374         }
375
376         select(i)
377         {
378                 this.tmp.hudbar.select(i);
379         }
380
381         getWieldedItem()
382         {
383                 return this.tmp.hudbar.getSelectedItem();
384         }
385
386         set onNextInventoryClose(func)
387         {
388                 this.tmp.inventory.onNextClose = func;
389         }
390 };
391
392 Object.assign(dragonblocks.Player.prototype, dragonblocks.MapInteraction);      // Mixin