aboutsummaryrefslogtreecommitdiff
path: root/Minecraft.World/FireworksRecipe.cpp
diff options
context:
space:
mode:
authordaoge <3523206925@qq.com>2026-03-03 03:04:10 +0800
committerGitHub <noreply@github.com>2026-03-03 03:04:10 +0800
commitb3feddfef372618c8a9d7a0abcaf18cfad866c18 (patch)
tree267761c3bb39241ba5c347bfbe2254d06686e287 /Minecraft.World/FireworksRecipe.cpp
parent84c31a2331f7a0ec85b9d438992e244f60e5020f (diff)
feat: TU19 (Dec 2014) Features & Content (#155)
* try to resolve merge conflict * feat: TU19 (Dec 2014) Features & Content (#32) * December 2014 files * Working release build * Fix compilation issues * Add sound to Windows64Media * Add DLC content and force Tutorial DLC * Revert "Add DLC content and force Tutorial DLC" This reverts commit 97a43994725008e35fceb984d5549df9c8cea470. * Disable broken light packing * Disable breakpoint during DLC texture map load Allows DLC loading but the DLC textures are still broken * Fix post build not working * ... * fix vs2022 build * fix cmake build --------- Co-authored-by: Loki <lokirautio@gmail.com>
Diffstat (limited to 'Minecraft.World/FireworksRecipe.cpp')
-rw-r--r--Minecraft.World/FireworksRecipe.cpp418
1 files changed, 418 insertions, 0 deletions
diff --git a/Minecraft.World/FireworksRecipe.cpp b/Minecraft.World/FireworksRecipe.cpp
new file mode 100644
index 00000000..a357c9cb
--- /dev/null
+++ b/Minecraft.World/FireworksRecipe.cpp
@@ -0,0 +1,418 @@
+#include "stdafx.h"
+#include "net.minecraft.world.item.h"
+#include "FireworksRecipe.h"
+
+DWORD FireworksRecipe::tlsIdx = 0;
+FireworksRecipe::ThreadStorage *FireworksRecipe::tlsDefault = NULL;
+
+FireworksRecipe::ThreadStorage::ThreadStorage()
+{
+ resultItem = nullptr;
+}
+
+void FireworksRecipe::CreateNewThreadStorage()
+{
+ ThreadStorage *tls = new ThreadStorage();
+ if(tlsDefault == NULL )
+ {
+ tlsIdx = TlsAlloc();
+ tlsDefault = tls;
+ }
+ TlsSetValue(tlsIdx, tls);
+}
+
+void FireworksRecipe::UseDefaultThreadStorage()
+{
+ TlsSetValue(tlsIdx, tlsDefault);
+}
+
+void FireworksRecipe::ReleaseThreadStorage()
+{
+ ThreadStorage *tls = (ThreadStorage *)TlsGetValue(tlsIdx);
+ if( tls == tlsDefault ) return;
+
+ delete tls;
+}
+
+void FireworksRecipe::setResultItem(shared_ptr<ItemInstance> item)
+{
+ ThreadStorage *tls = (ThreadStorage *)TlsGetValue(tlsIdx);
+ tls->resultItem = item;
+}
+
+FireworksRecipe::FireworksRecipe()
+{
+ //resultItem = nullptr;
+}
+
+bool FireworksRecipe::matches(shared_ptr<CraftingContainer> craftSlots, Level *level)
+{
+ shared_ptr<ItemInstance> resultItem = nullptr;
+
+ int paperCount = 0;
+ int sulphurCount = 0;
+ int colorCount = 0;
+ int chargeCount = 0;
+ int chargeComponents = 0;
+ int typeComponents = 0;
+
+ for (int slot = 0; slot < craftSlots->getContainerSize(); slot++)
+ {
+ shared_ptr<ItemInstance> item = craftSlots->getItem(slot);
+ if (item == NULL) continue;
+
+ if (item->id == Item::gunpowder_Id)
+ {
+ sulphurCount++;
+ }
+ else if (item->id == Item::fireworksCharge_Id)
+ {
+ chargeCount++;
+ }
+ else if (item->id == Item::dye_powder_Id)
+ {
+ colorCount++;
+ }
+ else if (item->id == Item::paper_Id)
+ {
+ paperCount++;
+ }
+ else if (item->id == Item::yellowDust_Id)
+ {
+ // glowstone dust gives flickering
+ chargeComponents++;
+ }
+ else if (item->id == Item::diamond_Id)
+ {
+ // diamonds give trails
+ chargeComponents++;
+ }
+ else if (item->id == Item::fireball_Id)
+ {
+ // fireball gives larger explosion
+ typeComponents++;
+ }
+ else if (item->id == Item::feather_Id)
+ {
+ // burst
+ typeComponents++;
+ }
+ else if (item->id == Item::goldNugget_Id)
+ {
+ // star
+ typeComponents++;
+ }
+ else if (item->id == Item::skull_Id)
+ {
+ // creeper
+ typeComponents++;
+ }
+ else
+ {
+ setResultItem(resultItem);
+ return false;
+ }
+ }
+ chargeComponents += colorCount + typeComponents;
+
+ if (sulphurCount > 3 || paperCount > 1)
+ {
+ setResultItem(resultItem);
+ return false;
+ }
+
+ // create fireworks
+ if (sulphurCount >= 1 && paperCount == 1 && chargeComponents == 0)
+ {
+ resultItem = shared_ptr<ItemInstance>( new ItemInstance(Item::fireworks) );
+ if (chargeCount > 0)
+ {
+ CompoundTag *itemTag = new CompoundTag();
+ CompoundTag *fireTag = new CompoundTag(FireworksItem::TAG_FIREWORKS);
+ ListTag<CompoundTag> *expTags = new ListTag<CompoundTag>(FireworksItem::TAG_EXPLOSIONS);
+
+ for (int slot = 0; slot < craftSlots->getContainerSize(); slot++)
+ {
+ shared_ptr<ItemInstance> item = craftSlots->getItem(slot);
+ if (item == NULL || item->id != Item::fireworksCharge_Id) continue;
+
+ if (item->hasTag() && item->getTag()->contains(FireworksItem::TAG_EXPLOSION))
+ {
+ expTags->add((CompoundTag *)item->getTag()->getCompound(FireworksItem::TAG_EXPLOSION)->copy());
+ }
+ }
+
+ fireTag->put(FireworksItem::TAG_EXPLOSIONS, expTags);
+ fireTag->putByte(FireworksItem::TAG_FLIGHT, (byte) sulphurCount);
+ itemTag->put(FireworksItem::TAG_FIREWORKS, fireTag);
+
+ resultItem->setTag(itemTag);
+ }
+ setResultItem(resultItem);
+ return true;
+ }
+ // create firecharge
+ if (sulphurCount == 1 && paperCount == 0 && chargeCount == 0 && colorCount > 0 && typeComponents <= 1)
+ {
+
+ resultItem = shared_ptr<ItemInstance>( new ItemInstance(Item::fireworksCharge) );
+ CompoundTag *itemTag = new CompoundTag();
+ CompoundTag *expTag = new CompoundTag(FireworksItem::TAG_EXPLOSION);
+
+ byte type = 0;
+
+ vector<int> colors;
+ for (int slot = 0; slot < craftSlots->getContainerSize(); slot++)
+ {
+ shared_ptr<ItemInstance> item = craftSlots->getItem(slot);
+ if (item == NULL) continue;
+
+ if (item->id == Item::dye_powder_Id)
+ {
+ colors.push_back(DyePowderItem::COLOR_RGB[item->getAuxValue()]);
+ }
+ else if (item->id == Item::yellowDust_Id)
+ {
+ // glowstone dust gives flickering
+ expTag->putBoolean(FireworksItem::TAG_E_FLICKER, true);
+ }
+ else if (item->id == Item::diamond_Id)
+ {
+ // diamonds give trails
+ expTag->putBoolean(FireworksItem::TAG_E_TRAIL, true);
+ }
+ else if (item->id == Item::fireball_Id)
+ {
+ type = FireworksItem::TYPE_BIG;
+ }
+ else if (item->id == Item::feather_Id)
+ {
+ type = FireworksItem::TYPE_BURST;
+ }
+ else if (item->id == Item::goldNugget_Id)
+ {
+ type = FireworksItem::TYPE_STAR;
+ }
+ else if (item->id == Item::skull_Id)
+ {
+ type = FireworksItem::TYPE_CREEPER;
+ }
+ }
+ intArray colorArray(colors.size());
+ for (int i = 0; i < colorArray.length; i++)
+ {
+ colorArray[i] = colors.at(i);
+ }
+ expTag->putIntArray(FireworksItem::TAG_E_COLORS, colorArray);
+
+ expTag->putByte(FireworksItem::TAG_E_TYPE, type);
+
+ itemTag->put(FireworksItem::TAG_EXPLOSION, expTag);
+ resultItem->setTag(itemTag);
+
+ setResultItem(resultItem);
+ return true;
+ }
+ // apply fade colors to firecharge
+ if (sulphurCount == 0 && paperCount == 0 && chargeCount == 1 && colorCount > 0 && colorCount == chargeComponents)
+ {
+
+ vector<int> colors;
+ for (int slot = 0; slot < craftSlots->getContainerSize(); slot++)
+ {
+ shared_ptr<ItemInstance> item = craftSlots->getItem(slot);
+ if (item == NULL) continue;
+
+ if (item->id == Item::dye_powder_Id)
+ {
+ colors.push_back(DyePowderItem::COLOR_RGB[item->getAuxValue()]);
+ }
+ else if (item->id == Item::fireworksCharge_Id)
+ {
+ resultItem = item->copy();
+ resultItem->count = 1;
+ }
+ }
+ intArray colorArray(colors.size());
+ for (int i = 0; i < colorArray.length; i++)
+ {
+ colorArray[i] = colors.at(i);
+ }
+ if (resultItem != NULL && resultItem->hasTag())
+ {
+ CompoundTag *compound = resultItem->getTag()->getCompound(FireworksItem::TAG_EXPLOSION);
+ if (compound == NULL)
+ {
+ delete colorArray.data;
+
+ setResultItem(resultItem);
+ return false;
+ }
+ compound->putIntArray(FireworksItem::TAG_E_FADECOLORS, colorArray);
+ }
+ else
+ {
+ delete colorArray.data;
+
+ setResultItem(resultItem);
+ return false;
+ }
+
+ setResultItem(resultItem);
+ return true;
+ }
+
+ setResultItem(resultItem);
+ return false;
+}
+
+shared_ptr<ItemInstance> FireworksRecipe::assemble(shared_ptr<CraftingContainer> craftSlots)
+{
+ ThreadStorage *tls = (ThreadStorage *)TlsGetValue(tlsIdx);
+ return tls->resultItem->copy();
+ //return resultItem->copy();
+}
+
+int FireworksRecipe::size()
+{
+ return 10;
+}
+
+const ItemInstance *FireworksRecipe::getResultItem()
+{
+ ThreadStorage *tls = (ThreadStorage *)TlsGetValue(tlsIdx);
+ return tls->resultItem.get();
+ //return resultItem.get();
+}
+
+void FireworksRecipe::updatePossibleRecipes(shared_ptr<CraftingContainer> craftSlots, bool *firework, bool *charge, bool *fade)
+{
+ *firework = false;
+ *charge = false;
+ *fade = false;
+
+ int paperCount = 0;
+ int sulphurCount = 0;
+ int colorCount = 0;
+ int chargeCount = 0;
+ int chargeComponents = 0;
+ int typeComponents = 0;
+
+ for (int slot = 0; slot < craftSlots->getContainerSize(); slot++)
+ {
+ shared_ptr<ItemInstance> item = craftSlots->getItem(slot);
+ if (item == NULL) continue;
+
+ if (item->id == Item::gunpowder_Id)
+ {
+ sulphurCount++;
+ }
+ else if (item->id == Item::fireworksCharge_Id)
+ {
+ chargeCount++;
+ }
+ else if (item->id == Item::dye_powder_Id)
+ {
+ colorCount++;
+ }
+ else if (item->id == Item::paper_Id)
+ {
+ paperCount++;
+ }
+ else if (item->id == Item::yellowDust_Id)
+ {
+ // glowstone dust gives flickering
+ chargeComponents++;
+ }
+ else if (item->id == Item::diamond_Id)
+ {
+ // diamonds give trails
+ chargeComponents++;
+ }
+ else if (item->id == Item::fireball_Id)
+ {
+ // fireball gives larger explosion
+ typeComponents++;
+ }
+ else if (item->id == Item::feather_Id)
+ {
+ // burst
+ typeComponents++;
+ }
+ else if (item->id == Item::goldNugget_Id)
+ {
+ // star
+ typeComponents++;
+ }
+ else if (item->id == Item::skull_Id)
+ {
+ // creeper
+ typeComponents++;
+ }
+ else
+ {
+ return;
+ }
+ }
+ chargeComponents += colorCount + typeComponents;
+
+ if (sulphurCount > 3 || paperCount > 1)
+ {
+ return;
+ }
+
+ // create fireworks
+ if ( paperCount <= 1 && chargeComponents == 0 )
+ {
+ *firework = true;
+ }
+ // create firecharge
+ if ( sulphurCount <= 1 && colorCount >= 0 && paperCount == 0 && chargeCount == 0 && typeComponents <= 1 )
+ {
+ *charge = true;
+ }
+ // apply fade colors to firecharge
+ if ( sulphurCount == 0 && paperCount == 0 && chargeCount <= 1 && colorCount >= 0 )
+ {
+ *fade = true;
+ }
+}
+
+bool FireworksRecipe::isValidIngredient(shared_ptr<ItemInstance> item, bool firework, bool charge, bool fade)
+{
+ bool valid = false;
+ switch(item->id)
+ {
+ case Item::gunpowder_Id:
+ valid = firework || charge;
+ break;
+ case Item::fireworksCharge_Id:
+ valid = firework || fade;
+ break;
+ case Item::dye_powder_Id:
+ valid = charge || fade;
+ break;
+ case Item::paper_Id:
+ valid = firework;
+ break;
+ case Item::yellowDust_Id:
+ valid = charge;
+ break;
+ case Item::diamond_Id:
+ valid = charge;
+ break;
+ case Item::fireball_Id:
+ valid = charge;
+ break;
+ case Item::feather_Id:
+ valid = charge;
+ break;
+ case Item::goldNugget_Id:
+ valid = charge;
+ break;
+ case Item::skull_Id:
+ valid = charge;
+ break;
+ }
+ return valid;
+} \ No newline at end of file