]> git.lizzy.rs Git - dragonblocks.git/blob - engine/item_stack.js
2345446bb58cded381acf8c78f03910892895a94
[dragonblocks.git] / engine / item_stack.js
1 /*
2  * item_stack.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.ItemStack = class extends EventTarget
25 {
26         constructor(itemstring)
27         {
28                 super();
29
30                 this.count = 0;
31                 this.item = null;
32                 this.id = dragonblocks.getToken();
33
34                 if (itemstring)
35                         this.deserialize(itemstring);
36         }
37
38         serialize()
39         {
40                 if (! this.item)
41                         return "";
42                 return this.item + " " + this.count;
43         }
44
45         deserialize(itemstring)
46         {
47                 this.item = itemstring ? itemstring.split(" ")[0] : null;
48                 this.count = itemstring ? parseInt(itemstring.split(" ")[1]) || 1 : 1;
49
50                 this.update();
51         }
52
53         getStacksize()
54         {
55                 return (this.toItem() && this.toItem().stacksize) || dragonblocks.settings.item.defaultStacksize;
56         }
57
58         trigger(eventType)
59         {
60                 this.dispatchEvent(new dragonblocks.ItemStack.Event(eventType, this));
61         }
62
63         update()
64         {
65                 if (this.count <= 0)
66                         this.item = null;
67
68                 if (! this.item)
69                         this.count = 0;
70
71                 this.trigger("update");
72         }
73
74         toItem()
75         {
76                 return dragonblocks.items[this.item];
77         }
78
79         swap(itemstack)
80         {
81                 [this.count, itemstack.count] = [itemstack.count, this.count];
82                 [this.item, itemstack.item] = [itemstack.item, this.item];
83
84                 itemstack.update();
85                 this.update();
86         }
87
88         clear()
89         {
90                 this.item = null;
91                 this.update();
92         }
93
94         addItems(itemstack, count)
95         {
96                 this.update();
97                 itemstack.update();
98
99                 if (! itemstack.item)
100                         return false;
101
102                 if (! this.item)
103                         this.item = itemstack.item;
104                 else if (this.item != itemstack.item)
105                         return false;
106
107                 if (this.count == this.getStacksize())
108                         return false;
109
110                 itemstack.count -= count;
111                 this.count += count;
112
113                 let less = -itemstack.count;
114                 if (less > 0) {
115                         itemstack.count += less;
116                         this.count -= less;
117                 }
118
119                 let more = this.count - this.getStacksize();
120                 if (more > 0) {
121                         this.count -= more;
122                         itemstack.count += more;
123                 }
124
125                 this.update();
126                 itemstack.update();
127
128                 return true;
129         }
130
131         add(itemstack)
132         {
133                 return this.addItems(itemstack, itemstack.count);
134         }
135
136         addOne(itemstack)
137         {
138                 return this.addItems(itemstack, 1);
139         }
140
141         addHalf(itemstack)
142         {
143                 return this.addItems(itemstack, Math.ceil(itemstack.count / 2));
144         }
145
146         getDisplay()
147         {
148                 return document.getElementById("dragonblocks.itemstack[" + this.id + "]");
149         }
150
151         draw(parent, x, y)
152         {
153                 let display = parent.appendChild(document.createElement("div"));
154                 display.id = "dragonblocks.itemstack[" + this.id + "]";
155                 display.stackid = this.id;
156                 display.style.borderStyle = "solid";
157                 display.style.borderWidth = "1px";
158                 display.style.borderColor = "#2D2D2D";
159                 display.style.width = dragonblocks.settings.inventory.scale + "px";
160                 display.style.height = dragonblocks.settings.inventory.scale + "px";
161                 display.style.backgroundColor = "#343434";
162                 display.style.position = "absolute";
163                 display.style.left = x + "px";
164                 display.style.top = y + "px";
165
166                 let countDisplay = display.appendChild(document.createElement("span"));
167                 countDisplay.id = "dragonblocks.itemstack[" + this.id + "].count";
168                 countDisplay.stackid = this.id;
169                 countDisplay.style.position = "absolute";
170                 countDisplay.style.right = "5px";
171                 countDisplay.style.bottom = "5px";
172                 countDisplay.style.color = "white";
173                 countDisplay.style.cursor = "default";
174
175                 let self = this;
176
177                 display.addEventListener("mousedown", event => {
178                         let out = dragonblocks.outStack;
179
180                         if (self.action)
181                                 return self.action(out, event.which);
182
183                         switch (event.which) {
184                                 case 1:
185                                         if (out.item)
186                                                 self.add(out) || self.swap(out);
187                                         else
188                                                 out.add(self);
189                                         break;
190
191                                 case 3:
192                                         if (out.item)
193                                                 self.addOne(out) || self.swap(out);
194                                         else
195                                                 out.addHalf(self);
196                         }
197                 });
198
199                 display.addEventListener("mouseover", event => {
200                         self.focused = true;
201                         self.redraw();
202                 });
203
204                 display.addEventListener("mouseleave", event => {
205                         self.focused = false;
206                         self.redraw();
207                 });
208
209                 this.addEventListener("update", _ => {
210                         self.redraw();
211                 });
212
213                 this.update();
214         }
215
216         redraw()
217         {
218                 let display = this.getDisplay();
219
220                 if (! display)
221                         return;
222
223                 let countDisplay = document.getElementById("dragonblocks.itemstack[" + this.id + "].count");
224
225                 if (this.item) {
226                         let item = this.toItem();
227
228                         display.title = item.desc;
229                         display.style.background = dragonblocks.getTexture(item.texture);
230
231                         if (this.count > 1)
232                                 countDisplay.innerHTML = this.count;
233                 } else {
234                         display.title = "";
235                         display.style.background = "none";
236
237                         countDisplay.innerHTML = "";
238                 }
239
240                 display.style.backgroundColor = this.focused ? "#7E7E7E" : "#343434";
241
242                 this.trigger("redraw");
243         }
244 };
245
246 dragonblocks.ItemStack.Event = class extends Event
247 {
248         constructor(type, stack)
249         {
250                 super(type);
251                 this.stack = stack;
252         }
253 };
254
255 dragonblocks.isValidItemstring = itemstring => {
256         let item = itemstring && itemstring.split(" ")[0];
257
258         if (item && ! dragonblocks.items[item])
259                 return false;
260
261         return true;
262 };