]> git.lizzy.rs Git - dragonblocks.git/blob - engine/map_interaction.js
Fix z-index of crack when digging a node with a z-index below the player's
[dragonblocks.git] / engine / map_interaction.js
1 /*
2  * map_interaction.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.MapInteraction = {
25         initMapInteraction()
26         {
27                 let crack = document.getElementById("dragonblocks.map").appendChild(document.createElement("div"));
28                 crack.id = "dragonblocks.crack[" + this.id + "]";
29                 crack.style.position = "absolute";
30                 crack.style.visibility = "hidden";
31                 crack.style.backgroundSize = "cover";
32                 crack.style.height = dragonblocks.settings.map.scale + "px";
33                 crack.style.width = dragonblocks.settings.map.scale + "px";
34                 crack.style.boxShadow = "0 0 0 1px black inset";
35                 crack.style.zIndex = 2;
36
37                 let self = this;
38
39                 crack.addEventListener("mouseleave", event => {
40                         self.digStop();
41                         let [x, y] = dragonblocks.map.getScreenCoordinates(event.srcElement.offsetLeft, event.srcElement.offsetTop);
42                         dragonblocks.map.getNodeDisplay(x, y).style.boxShadow = "none";
43                 });
44
45                 crack.addEventListener("mouseover", event => {
46                         let [x, y] = dragonblocks.map.getScreenCoordinates(event.srcElement.offsetLeft + document.getElementById("dragonblocks.map").offsetLeft, event.srcElement.offsetTop + document.getElementById("dragonblocks.map").offsetTop);
47                         dragonblocks.map.getNodeDisplay(x, y).style.boxShadow = "0 0 0 1px black inset";
48                 });
49         },
50
51         dig(x, y)
52         {
53                 let node = dragonblocks.getNode(x, y);
54
55                 if (! node)
56                         return false;
57
58                 let nodeDef = node.toNode();
59                 if (nodeDef.ondig && nodeDef.ondig(x, y) == false)
60                         return false;
61
62                 for (let func of dragonblocks.onDigNodeCallbacks)
63                         if (func(x, y) == false)
64                                 return false;
65
66                 nodeDef.playSound("dug");
67
68                 dragonblocks.setNode(x, y, "air");
69                 dragonblocks.map.activate(x, y);
70
71                 return true;
72         },
73
74         digStart(x, y)
75         {
76                 let node = dragonblocks.getNode(x, y);
77                 let nodeDef = node.toNode();
78
79                 node.meta.hardness = nodeDef.hardness;
80                 node.meta.causedDamage = 0;
81
82                 if (! this.canReach(x, y))
83                         return;
84
85                 let crack = document.getElementById("dragonblocks.crack[" + this.id + "]")
86                 crack.style.visibility = "visible";
87                 crack.style.left = (x - dragonblocks.map.displayLeft) * dragonblocks.settings.map.scale + "px";
88                 crack.style.top = (y - dragonblocks.map.displayTop) * dragonblocks.settings.map.scale + "px";
89
90                 dragonblocks.log("Punched Node at (" + x + ", " + y + ")");
91
92                 nodeDef.onpunch && nodeDef.onpunch(x,y);
93
94                 for (let func of dragonblocks.onPunchNodeCallbacks)
95                         func(x, y);
96
97                 dragonblocks.map.activate(x, y);
98
99                 this.digTick(x, y);
100         },
101
102         digTick(x, y)
103         {
104                 let self = this;
105
106                 let node = dragonblocks.getNode(x, y);
107                 if (! node)
108                         return;
109
110                 let nodeDef = node.toNode();
111
112                 let damage = this.tool.calculateDamage(nodeDef);
113                 if (damage == -1)
114                         damage = this.tmp.defaultTool.calculateDamage(nodeDef);
115
116                 node.meta.hardness -= damage;
117                 node.meta.causedDamage += damage;
118
119                 if (isNaN(node.meta.hardness) || node.meta.hardness <= 0) {
120                         this.digEnd(x, y);
121                 } else {
122                         nodeDef.playSound("dig");
123
124                         let crack = document.getElementById("dragonblocks.crack[" + this.id + "]");
125                         crack.style.background = dragonblocks.getTexture("crack" + Math.floor(node.meta.causedDamage / nodeDef.hardness * 5) + ".png");
126                         crack.style.backgroundSize = "cover";
127                         crack.style.zIndex = nodeDef.zIndex || "1";
128
129                         this.tmp.digTimeout = setTimeout(_ => {
130                                 self.digTick(x, y);
131                         }, this.tool.interval);
132                 }
133         },
134
135         digEnd(x, y)
136         {
137                 let node = dragonblocks.getNode(x, y);
138
139                 if (! node)
140                         return;
141
142                 let nodeDef = node.toNode();
143
144                 if (this.dig(x, y))
145                         dragonblocks.handleNodeDrop(this.tmp.mainInventory, nodeDef, x, y);
146
147                 document.getElementById("dragonblocks.crack[" + this.id + "]").style.visibility = "hidden";
148         },
149
150         digStop()
151         {
152                 clearTimeout(this.tmp.digTimeout);
153                 document.getElementById("dragonblocks.crack[" + this.id + "]").style.visibility = "hidden";
154         },
155
156         place(x, y, node)
157         {
158                 let oldNode = dragonblocks.getNode(x, y);
159
160                 if (! oldNode || oldNode.stable)
161                         return false;
162
163                 if (node.onplace && node.onplace(x, y) == false)
164                         return false;
165
166                 for (let func of dragonblocks.onPlaceNodeCallbacks)
167                         if (func(node, x, y) == false)
168                                 return false;
169
170                 dragonblocks.setNode(x, y, node);
171                 dragonblocks.map.activate(x, y);
172
173                 node.playSound("place");
174
175                 return true;
176         },
177
178         build(x, y)
179         {
180                 if(this.canReach(x, y)) {
181                         let oldNodeDef = dragonblocks.getNode(x, y).toNode();
182                         oldNodeDef.onclick && oldNodeDef.onclick(x, y);
183
184                         for (let func of dragonblocks.onClickNodeCallbacks)
185                                 func(x, y);
186
187                         if (this.touch(x, y))
188                                 return;
189
190                         let wielded = this.getWieldedItem();
191                         let itemstack = new dragonblocks.ItemStack();
192
193                         if(! itemstack.addOne(wielded))
194                                 return;
195
196                         let itemDef = itemstack.toItem();
197
198                         if (itemDef instanceof dragonblocks.Node) {
199                                 if (! this.place(x, y, itemDef) || this.meta.creative)
200                                         wielded.add(itemstack);
201                         } else {
202                                 if (! itemDef.onuse || ! itemDef.onuse(x, y)) {
203                                         wielded.add(itemstack);
204                                 } else {
205                                         for (let func of dragonblocks.onUseItemCallbacks)
206                                                 func(itemDef, x, y);
207
208                                         if (this.meta.creative)
209                                                 wielded.add(itemstack);
210                                 }
211                         }
212                 }
213         },
214
215         canReach(x, y)
216         {
217                 return this.meta.creative || Math.sqrt(Math.pow(x - this.x, 2) + Math.pow(y - this.y, 2)) <= this.tool.range;
218         }
219 };
220
221 dragonblocks.handleNodeDrop = (inventory, nodeDef, x, y) => {
222         dragonblocks.dropItem(inventory.add((nodeDef.drops instanceof Function) ? nodeDef.drops() : nodeDef.drops), x + 0.2, y + 0.2);
223 };