the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
1#include "stdafx.h"
2#include "net.minecraft.world.item.h"
3#include "FireworksRecipe.h"
4
5DWORD FireworksRecipe::tlsIdx = 0;
6FireworksRecipe::ThreadStorage *FireworksRecipe::tlsDefault = NULL;
7
8FireworksRecipe::ThreadStorage::ThreadStorage()
9{
10 resultItem = nullptr;
11}
12
13void FireworksRecipe::CreateNewThreadStorage()
14{
15 ThreadStorage *tls = new ThreadStorage();
16 if(tlsDefault == NULL )
17 {
18 tlsIdx = TlsAlloc();
19 tlsDefault = tls;
20 }
21 TlsSetValue(tlsIdx, tls);
22}
23
24void FireworksRecipe::UseDefaultThreadStorage()
25{
26 TlsSetValue(tlsIdx, tlsDefault);
27}
28
29void FireworksRecipe::ReleaseThreadStorage()
30{
31 ThreadStorage *tls = (ThreadStorage *)TlsGetValue(tlsIdx);
32 if( tls == tlsDefault ) return;
33
34 delete tls;
35}
36
37void FireworksRecipe::setResultItem(shared_ptr<ItemInstance> item)
38{
39 ThreadStorage *tls = (ThreadStorage *)TlsGetValue(tlsIdx);
40 tls->resultItem = item;
41}
42
43FireworksRecipe::FireworksRecipe()
44{
45 //resultItem = nullptr;
46}
47
48bool FireworksRecipe::matches(shared_ptr<CraftingContainer> craftSlots, Level *level)
49{
50 shared_ptr<ItemInstance> resultItem = nullptr;
51
52 int paperCount = 0;
53 int sulphurCount = 0;
54 int colorCount = 0;
55 int chargeCount = 0;
56 int chargeComponents = 0;
57 int typeComponents = 0;
58
59 for (int slot = 0; slot < craftSlots->getContainerSize(); slot++)
60 {
61 shared_ptr<ItemInstance> item = craftSlots->getItem(slot);
62 if (item == NULL) continue;
63
64 if (item->id == Item::gunpowder_Id)
65 {
66 sulphurCount++;
67 }
68 else if (item->id == Item::fireworksCharge_Id)
69 {
70 chargeCount++;
71 }
72 else if (item->id == Item::dye_powder_Id)
73 {
74 colorCount++;
75 }
76 else if (item->id == Item::paper_Id)
77 {
78 paperCount++;
79 }
80 else if (item->id == Item::yellowDust_Id)
81 {
82 // glowstone dust gives flickering
83 chargeComponents++;
84 }
85 else if (item->id == Item::diamond_Id)
86 {
87 // diamonds give trails
88 chargeComponents++;
89 }
90 else if (item->id == Item::fireball_Id)
91 {
92 // fireball gives larger explosion
93 typeComponents++;
94 }
95 else if (item->id == Item::feather_Id)
96 {
97 // burst
98 typeComponents++;
99 }
100 else if (item->id == Item::goldNugget_Id)
101 {
102 // star
103 typeComponents++;
104 }
105 else if (item->id == Item::skull_Id)
106 {
107 // creeper
108 typeComponents++;
109 }
110 else
111 {
112 setResultItem(resultItem);
113 return false;
114 }
115 }
116 chargeComponents += colorCount + typeComponents;
117
118 if (sulphurCount > 3 || paperCount > 1)
119 {
120 setResultItem(resultItem);
121 return false;
122 }
123
124 // create fireworks
125 if (sulphurCount >= 1 && paperCount == 1 && chargeComponents == 0)
126 {
127 resultItem = shared_ptr<ItemInstance>( new ItemInstance(Item::fireworks) );
128 if (chargeCount > 0)
129 {
130 CompoundTag *itemTag = new CompoundTag();
131 CompoundTag *fireTag = new CompoundTag(FireworksItem::TAG_FIREWORKS);
132 ListTag<CompoundTag> *expTags = new ListTag<CompoundTag>(FireworksItem::TAG_EXPLOSIONS);
133
134 for (int slot = 0; slot < craftSlots->getContainerSize(); slot++)
135 {
136 shared_ptr<ItemInstance> item = craftSlots->getItem(slot);
137 if (item == NULL || item->id != Item::fireworksCharge_Id) continue;
138
139 if (item->hasTag() && item->getTag()->contains(FireworksItem::TAG_EXPLOSION))
140 {
141 expTags->add((CompoundTag *)item->getTag()->getCompound(FireworksItem::TAG_EXPLOSION)->copy());
142 }
143 }
144
145 fireTag->put(FireworksItem::TAG_EXPLOSIONS, expTags);
146 fireTag->putByte(FireworksItem::TAG_FLIGHT, (byte) sulphurCount);
147 itemTag->put(FireworksItem::TAG_FIREWORKS, fireTag);
148
149 resultItem->setTag(itemTag);
150 }
151 setResultItem(resultItem);
152 return true;
153 }
154 // create firecharge
155 if (sulphurCount == 1 && paperCount == 0 && chargeCount == 0 && colorCount > 0 && typeComponents <= 1)
156 {
157
158 resultItem = shared_ptr<ItemInstance>( new ItemInstance(Item::fireworksCharge) );
159 CompoundTag *itemTag = new CompoundTag();
160 CompoundTag *expTag = new CompoundTag(FireworksItem::TAG_EXPLOSION);
161
162 byte type = 0;
163
164 vector<int> colors;
165 for (int slot = 0; slot < craftSlots->getContainerSize(); slot++)
166 {
167 shared_ptr<ItemInstance> item = craftSlots->getItem(slot);
168 if (item == NULL) continue;
169
170 if (item->id == Item::dye_powder_Id)
171 {
172 colors.push_back(DyePowderItem::COLOR_RGB[item->getAuxValue()]);
173 }
174 else if (item->id == Item::yellowDust_Id)
175 {
176 // glowstone dust gives flickering
177 expTag->putBoolean(FireworksItem::TAG_E_FLICKER, true);
178 }
179 else if (item->id == Item::diamond_Id)
180 {
181 // diamonds give trails
182 expTag->putBoolean(FireworksItem::TAG_E_TRAIL, true);
183 }
184 else if (item->id == Item::fireball_Id)
185 {
186 type = FireworksItem::TYPE_BIG;
187 }
188 else if (item->id == Item::feather_Id)
189 {
190 type = FireworksItem::TYPE_BURST;
191 }
192 else if (item->id == Item::goldNugget_Id)
193 {
194 type = FireworksItem::TYPE_STAR;
195 }
196 else if (item->id == Item::skull_Id)
197 {
198 type = FireworksItem::TYPE_CREEPER;
199 }
200 }
201 intArray colorArray(colors.size());
202 for (int i = 0; i < colorArray.length; i++)
203 {
204 colorArray[i] = colors.at(i);
205 }
206 expTag->putIntArray(FireworksItem::TAG_E_COLORS, colorArray);
207
208 expTag->putByte(FireworksItem::TAG_E_TYPE, type);
209
210 itemTag->put(FireworksItem::TAG_EXPLOSION, expTag);
211 resultItem->setTag(itemTag);
212
213 setResultItem(resultItem);
214 return true;
215 }
216 // apply fade colors to firecharge
217 if (sulphurCount == 0 && paperCount == 0 && chargeCount == 1 && colorCount > 0 && colorCount == chargeComponents)
218 {
219
220 vector<int> colors;
221 for (int slot = 0; slot < craftSlots->getContainerSize(); slot++)
222 {
223 shared_ptr<ItemInstance> item = craftSlots->getItem(slot);
224 if (item == NULL) continue;
225
226 if (item->id == Item::dye_powder_Id)
227 {
228 colors.push_back(DyePowderItem::COLOR_RGB[item->getAuxValue()]);
229 }
230 else if (item->id == Item::fireworksCharge_Id)
231 {
232 resultItem = item->copy();
233 resultItem->count = 1;
234 }
235 }
236 intArray colorArray(colors.size());
237 for (int i = 0; i < colorArray.length; i++)
238 {
239 colorArray[i] = colors.at(i);
240 }
241 if (resultItem != NULL && resultItem->hasTag())
242 {
243 CompoundTag *compound = resultItem->getTag()->getCompound(FireworksItem::TAG_EXPLOSION);
244 if (compound == NULL)
245 {
246 delete colorArray.data;
247
248 setResultItem(resultItem);
249 return false;
250 }
251 compound->putIntArray(FireworksItem::TAG_E_FADECOLORS, colorArray);
252 }
253 else
254 {
255 delete colorArray.data;
256
257 setResultItem(resultItem);
258 return false;
259 }
260
261 setResultItem(resultItem);
262 return true;
263 }
264
265 setResultItem(resultItem);
266 return false;
267}
268
269shared_ptr<ItemInstance> FireworksRecipe::assemble(shared_ptr<CraftingContainer> craftSlots)
270{
271 ThreadStorage *tls = (ThreadStorage *)TlsGetValue(tlsIdx);
272 return tls->resultItem->copy();
273 //return resultItem->copy();
274}
275
276int FireworksRecipe::size()
277{
278 return 10;
279}
280
281const ItemInstance *FireworksRecipe::getResultItem()
282{
283 ThreadStorage *tls = (ThreadStorage *)TlsGetValue(tlsIdx);
284 return tls->resultItem.get();
285 //return resultItem.get();
286}
287
288void FireworksRecipe::updatePossibleRecipes(shared_ptr<CraftingContainer> craftSlots, bool *firework, bool *charge, bool *fade)
289{
290 *firework = false;
291 *charge = false;
292 *fade = false;
293
294 int paperCount = 0;
295 int sulphurCount = 0;
296 int colorCount = 0;
297 int chargeCount = 0;
298 int chargeComponents = 0;
299 int typeComponents = 0;
300
301 for (int slot = 0; slot < craftSlots->getContainerSize(); slot++)
302 {
303 shared_ptr<ItemInstance> item = craftSlots->getItem(slot);
304 if (item == NULL) continue;
305
306 if (item->id == Item::gunpowder_Id)
307 {
308 sulphurCount++;
309 }
310 else if (item->id == Item::fireworksCharge_Id)
311 {
312 chargeCount++;
313 }
314 else if (item->id == Item::dye_powder_Id)
315 {
316 colorCount++;
317 }
318 else if (item->id == Item::paper_Id)
319 {
320 paperCount++;
321 }
322 else if (item->id == Item::yellowDust_Id)
323 {
324 // glowstone dust gives flickering
325 chargeComponents++;
326 }
327 else if (item->id == Item::diamond_Id)
328 {
329 // diamonds give trails
330 chargeComponents++;
331 }
332 else if (item->id == Item::fireball_Id)
333 {
334 // fireball gives larger explosion
335 typeComponents++;
336 }
337 else if (item->id == Item::feather_Id)
338 {
339 // burst
340 typeComponents++;
341 }
342 else if (item->id == Item::goldNugget_Id)
343 {
344 // star
345 typeComponents++;
346 }
347 else if (item->id == Item::skull_Id)
348 {
349 // creeper
350 typeComponents++;
351 }
352 else
353 {
354 return;
355 }
356 }
357 chargeComponents += colorCount + typeComponents;
358
359 if (sulphurCount > 3 || paperCount > 1)
360 {
361 return;
362 }
363
364 // create fireworks
365 if ( paperCount <= 1 && chargeComponents == 0 )
366 {
367 *firework = true;
368 }
369 // create firecharge
370 if ( sulphurCount <= 1 && colorCount >= 0 && paperCount == 0 && chargeCount == 0 && typeComponents <= 1 )
371 {
372 *charge = true;
373 }
374 // apply fade colors to firecharge
375 if ( sulphurCount == 0 && paperCount == 0 && chargeCount <= 1 && colorCount >= 0 )
376 {
377 *fade = true;
378 }
379}
380
381bool FireworksRecipe::isValidIngredient(shared_ptr<ItemInstance> item, bool firework, bool charge, bool fade)
382{
383 bool valid = false;
384 switch(item->id)
385 {
386 case Item::gunpowder_Id:
387 valid = firework || charge;
388 break;
389 case Item::fireworksCharge_Id:
390 valid = firework || fade;
391 break;
392 case Item::dye_powder_Id:
393 valid = charge || fade;
394 break;
395 case Item::paper_Id:
396 valid = firework;
397 break;
398 case Item::yellowDust_Id:
399 valid = charge;
400 break;
401 case Item::diamond_Id:
402 valid = charge;
403 break;
404 case Item::fireball_Id:
405 valid = charge;
406 break;
407 case Item::feather_Id:
408 valid = charge;
409 break;
410 case Item::goldNugget_Id:
411 valid = charge;
412 break;
413 case Item::skull_Id:
414 valid = charge;
415 break;
416 }
417 return valid;
418}