mirror of
https://github.com/4jcraft/4jcraft.git
synced 2026-04-23 19:43:42 +00:00
337 lines
11 KiB
C++
337 lines
11 KiB
C++
#include "../Platform/stdafx.h"
|
|
#include "../Headers/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(std::shared_ptr<ItemInstance> item) {
|
|
ThreadStorage* tls = (ThreadStorage*)TlsGetValue(tlsIdx);
|
|
tls->resultItem = item;
|
|
}
|
|
|
|
FireworksRecipe::FireworksRecipe() {
|
|
// resultItem = nullptr;
|
|
}
|
|
|
|
bool FireworksRecipe::matches(std::shared_ptr<CraftingContainer> craftSlots,
|
|
Level* level) {
|
|
std::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++) {
|
|
std::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 =
|
|
std::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++) {
|
|
std::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, (uint8_t)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 = std::shared_ptr<ItemInstance>(
|
|
new ItemInstance(Item::fireworksCharge));
|
|
CompoundTag* itemTag = new CompoundTag();
|
|
CompoundTag* expTag = new CompoundTag(FireworksItem::TAG_EXPLOSION);
|
|
|
|
uint8_t type = 0;
|
|
|
|
std::vector<int> colors;
|
|
for (int slot = 0; slot < craftSlots->getContainerSize(); slot++) {
|
|
std::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) {
|
|
std::vector<int> colors;
|
|
for (int slot = 0; slot < craftSlots->getContainerSize(); slot++) {
|
|
std::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;
|
|
}
|
|
|
|
std::shared_ptr<ItemInstance> FireworksRecipe::assemble(
|
|
std::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(
|
|
std::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++) {
|
|
std::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(std::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;
|
|
} |