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