// package net.minecraft.world.item.crafting; // // import net.minecraft.world.inventory.CraftingContainer; // import net.minecraft.world.item.ItemInstance; #include "stdafx.h" #include "net.minecraft.world.item.h" #include "net.minecraft.world.inventory.h" #include "Tile.h" #include "Recipy.h" #include "Recipes.h" #include "ShapedRecipy.h" // 4J-PB - for new crafting - Adding group to define type of item that the recipe produces ShapedRecipy::ShapedRecipy(int width, int height, ItemInstance **recipeItems, ItemInstance *result, int iGroup) : resultId(result->id) { this->width = width; this->height = height; this->recipeItems = recipeItems; this->result = result; this->group = iGroup; _keepTag = false; } ShapedRecipy::~ShapedRecipy() { // todo: why does this cause a error when clearing out these specifically? // might be leaking memory here but im not sure cause it crashes when you clear them, so we dont clear them /*for (int x = 0; x < 3; x++) { for (int y = 0; y < 3; y++) { if (x < width && y < height) { delete recipeItems[x + y * width]; } } }*/ delete[] recipeItems; delete result; recipeItems = nullptr; result = nullptr; } const int ShapedRecipy::getGroup() { return group; } const ItemInstance *ShapedRecipy::getResultItem() { return result; } bool ShapedRecipy::matches(shared_ptr craftSlots, Level *level) { for (int xOffs = 0; xOffs <= (3 - width); xOffs++) { for (int yOffs = 0; yOffs <= (3 - height); yOffs++) { if (matches(craftSlots, xOffs, yOffs, true)) return true; if (matches(craftSlots, xOffs, yOffs, false)) return true; } } return false; } bool ShapedRecipy::matches(shared_ptr craftSlots, int xOffs, int yOffs, bool xFlip) { for (int x = 0; x < 3; x++) { for (int y = 0; y < 3; y++) { int xs = x - xOffs; int ys = y - yOffs; ItemInstance *expected = nullptr; if (xs >= 0 && ys >= 0 && xs < width && ys < height) { if (xFlip) expected = recipeItems[(width - xs - 1) + ys * width]; else expected = recipeItems[xs + ys * width]; } shared_ptr item = craftSlots->getItem(x, y); if (item == nullptr && expected == nullptr) { continue; } if ((item == nullptr && expected != nullptr) || (item != nullptr && expected == nullptr)) { return false; } if (expected->id != item->id) { return false; } if (expected->getAuxValue() != Recipes::ANY_AUX_VALUE && expected->getAuxValue() != item->getAuxValue()) { return false; } } } return true; } shared_ptr ShapedRecipy::assemble(shared_ptr craftSlots) { shared_ptr result = getResultItem()->copy(); if (_keepTag && craftSlots != nullptr) { for (int i = 0; i < craftSlots->getContainerSize(); i++) { shared_ptr item = craftSlots->getItem(i); if (item != nullptr && item->hasTag()) { result->setTag(static_cast(item->tag->copy())); } } } return result; } int ShapedRecipy::size() { return width * height; } // 4J-PB bool ShapedRecipy::reqs(int iRecipe) { app.DebugPrintf("ShapedRecipy %d\n",iRecipe); int iCount=0; for (int x = 0; x < 3; x++) { for (int y = 0; y < 3; y++) { if (x < width && y < height) { ItemInstance *expected = recipeItems[x+y*width]; if (expected!=nullptr) { //printf("\tIngredient %d is %d\n",iCount++,expected->id); } } } } return false; } void ShapedRecipy::reqs(INGREDIENTS_REQUIRED *pIngReq) { //printf("ShapedRecipy %d\n",iRecipe); int iCount=0; bool bFound; int j; INGREDIENTS_REQUIRED TempIngReq; TempIngReq.iIngC=0; TempIngReq.iType = ((width>2) ||(height>2))?RECIPE_TYPE_3x3:RECIPE_TYPE_2x2; // 3x3 // 3x3 TempIngReq.uiGridA = new unsigned int [9]; TempIngReq.iIngIDA= new int [9]; TempIngReq.iIngValA = new int [9]; TempIngReq.iIngAuxValA = new int [9]; ZeroMemory(TempIngReq.iIngIDA,sizeof(int)*9); ZeroMemory(TempIngReq.iIngValA,sizeof(int)*9); memset(TempIngReq.iIngAuxValA,Recipes::ANY_AUX_VALUE,sizeof(int)*9); ZeroMemory(TempIngReq.uiGridA,sizeof(unsigned int)*9); for (int x = 0; x < 3; x++) { for (int y = 0; y < 3; y++) { if (x < width && y < height) { ItemInstance *expected = recipeItems[x+y*width]; if (expected!=nullptr) { int iAuxVal = expected->getAuxValue(); TempIngReq.uiGridA[x+y*3]=expected->id | iAuxVal<<24; bFound=false; for(j=0;jid) && (iAuxVal == Recipes::ANY_AUX_VALUE || TempIngReq.iIngAuxValA[j] == iAuxVal)) { bFound= true; break; } } if(bFound) { TempIngReq.iIngValA[j]++; } else { TempIngReq.iIngIDA[TempIngReq.iIngC]=expected->id; TempIngReq.iIngAuxValA[TempIngReq.iIngC]=iAuxVal; TempIngReq.iIngValA[TempIngReq.iIngC++]++; } //printf("\tIngredient %d is %d\n",iCount++,expected->id); } } } } pIngReq->iIngIDA= new int [TempIngReq.iIngC]; pIngReq->iIngValA= new int [TempIngReq.iIngC]; pIngReq->iIngAuxValA = new int [TempIngReq.iIngC]; pIngReq->uiGridA = new unsigned int [9]; pIngReq->iIngC=TempIngReq.iIngC; pIngReq->iType=TempIngReq.iType; pIngReq->pRecipy=this; for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i) { pIngReq->bCanMake[i]=false; } for(j=0;j<9;j++) { pIngReq->uiGridA[j]=TempIngReq.uiGridA[j]; } if(pIngReq->iIngC!=0) { memcpy(pIngReq->iIngIDA,TempIngReq.iIngIDA,sizeof(int)*TempIngReq.iIngC); memcpy(pIngReq->iIngValA,TempIngReq.iIngValA,sizeof(int)*TempIngReq.iIngC); memcpy(pIngReq->iIngAuxValA,TempIngReq.iIngAuxValA,sizeof(int)*TempIngReq.iIngC); } memcpy(pIngReq->uiGridA,TempIngReq.uiGridA,sizeof(unsigned int)*9); delete [] TempIngReq.iIngIDA; delete [] TempIngReq.iIngValA; delete [] TempIngReq.iIngAuxValA; delete [] TempIngReq.uiGridA; } ShapedRecipy *ShapedRecipy::keepTag() { _keepTag = true; return this; } void ShapedRecipy::writeToStream(DataOutputStream* dos) { dos->writeByte(2); dos->writeByte(this->group); //write result item, it should always be valid { dos->writeShort(this->result->id); dos->writeByte(this->result->count); dos->writeShort(this->result->getAuxValue()); Packet::writeNbt(this->result->tag, dos); } dos->writeByte((this->width << 2) | this->height); for (int i = 0; i < (this->width * this->height); i++) { ItemInstance* ingredients_item = this->recipeItems[i]; dos->writeBoolean(ingredients_item == nullptr); if (ingredients_item == nullptr) continue; dos->writeShort(ingredients_item->id); dos->writeShort(ingredients_item->getAuxValue()); Packet::writeNbt(ingredients_item->tag, dos); } } ShapedRecipy* ShapedRecipy::readFromStream(DataInputStream* dis) { int groupType = dis->readByte(); int resultItemID = dis->readShort(); int resultItemCount = dis->readByte(); int resultItemAux = dis->readShort(); ItemInstance* resultItem = new ItemInstance(resultItemID, resultItemCount, 0); resultItem->setRawAuxValue(resultItemAux); resultItem->tag = Packet::readNbt(dis); unsigned char packedSize = dis->readByte(); int width = (packedSize >> 2) & 0x3; int height = packedSize & 0x3; ItemInstance** ids = new ItemInstance*[width * height]; for (int i = 0; i < width * height; i++) { ItemInstance* ingredients_item = nullptr; bool isNull = dis->readBoolean(); if (!isNull) { int itemId = dis->readShort(); int itemAux = dis->readShort(); ingredients_item = new ItemInstance(itemId, 1, 0); ingredients_item->setRawAuxValue(itemAux); ingredients_item->tag = Packet::readNbt(dis); } ids[i] = ingredients_item; } return new ShapedRecipy(width, height, ids, resultItem, groupType); }