From b691c43c44ff180d10e7d4a9afc83b98551ff586 Mon Sep 17 00:00:00 2001 From: daoge_cmd <3523206925@qq.com> Date: Sun, 1 Mar 2026 12:16:08 +0800 Subject: Initial commit --- Minecraft.World/MerchantRecipeList.cpp | 195 +++++++++++++++++++++++++++++++++ 1 file changed, 195 insertions(+) create mode 100644 Minecraft.World/MerchantRecipeList.cpp (limited to 'Minecraft.World/MerchantRecipeList.cpp') diff --git a/Minecraft.World/MerchantRecipeList.cpp b/Minecraft.World/MerchantRecipeList.cpp new file mode 100644 index 00000000..bd7a126c --- /dev/null +++ b/Minecraft.World/MerchantRecipeList.cpp @@ -0,0 +1,195 @@ +#include "stdafx.h" +#include "net.minecraft.world.item.trading.h" +#include "MerchantRecipeList.h" + +MerchantRecipeList::MerchantRecipeList() +{ +} + +MerchantRecipeList::MerchantRecipeList(CompoundTag *tag) +{ + load(tag); +} + +MerchantRecipeList::~MerchantRecipeList() +{ + for(AUTO_VAR(it, m_recipes.begin()); it != m_recipes.end(); ++it) + { + delete (*it); + } +} + +MerchantRecipe *MerchantRecipeList::getRecipeFor(shared_ptr buyA, shared_ptr buyB, int selectionHint) +{ + if (selectionHint > 0 && selectionHint < m_recipes.size()) + { + // attempt to match vs the hint + MerchantRecipe *r = m_recipes.at(selectionHint); + if (buyA->id == r->getBuyAItem()->id && ((buyB == NULL && !r->hasSecondaryBuyItem()) || (r->hasSecondaryBuyItem() && buyB != NULL && r->getBuyBItem()->id == buyB->id))) + { + if (buyA->count >= r->getBuyAItem()->count && (!r->hasSecondaryBuyItem() || buyB->count >= r->getBuyBItem()->count)) + { + return r; + } + } + return NULL; + } + for (int i = 0; i < m_recipes.size(); i++) + { + MerchantRecipe *r = m_recipes.at(i); + if (buyA->id == r->getBuyAItem()->id && buyA->count >= r->getBuyAItem()->count + && ((!r->hasSecondaryBuyItem() && buyB == NULL) || (r->hasSecondaryBuyItem() && buyB != NULL && r->getBuyBItem()->id == buyB->id && buyB->count >= r->getBuyBItem()->count))) + { + return r; + } + } + return NULL; +} + +bool MerchantRecipeList::addIfNewOrBetter(MerchantRecipe *recipe) +{ + bool added = false; + for (int i = 0; i < m_recipes.size(); i++) + { + MerchantRecipe *r = m_recipes.at(i); + if (recipe->isSame(r)) + { + if (recipe->isSameSameButBetter(r)) + { + delete m_recipes[i]; + m_recipes[i] = recipe; + added = true; + } + return added; + } + } + m_recipes.push_back(recipe); + return true; +} + +MerchantRecipe *MerchantRecipeList::getMatchingRecipeFor(shared_ptr buy, shared_ptr buyB, shared_ptr sell) +{ + for (int i = 0; i < m_recipes.size(); i++) + { + MerchantRecipe *r = m_recipes.at(i); + if (buy->id == r->getBuyAItem()->id && buy->count >= r->getBuyAItem()->count && sell->id == r->getSellItem()->id) + { + if (!r->hasSecondaryBuyItem() || (buyB != NULL && buyB->id == r->getBuyBItem()->id && buyB->count >= r->getBuyBItem()->count)) + { + return r; + } + } + } + return NULL; +} + +void MerchantRecipeList::writeToStream(DataOutputStream *stream) +{ + stream->writeByte((byte) (m_recipes.size() & 0xff)); + for (int i = 0; i < m_recipes.size(); i++) + { + MerchantRecipe *r = m_recipes.at(i); + Packet::writeItem(r->getBuyAItem(), stream); + Packet::writeItem(r->getSellItem(), stream); + + shared_ptr buyBItem = r->getBuyBItem(); + stream->writeBoolean(buyBItem != NULL); + if (buyBItem != NULL) + { + Packet::writeItem(buyBItem, stream); + } + stream->writeBoolean(r->isDeprecated()); + stream->writeInt(r->getUses()); + stream->writeInt(r->getMaxUses()); + } +} + +MerchantRecipeList *MerchantRecipeList::createFromStream(DataInputStream *stream) +{ + MerchantRecipeList *list = new MerchantRecipeList(); + + int count = (int) (stream->readByte() & 0xff); + for (int i = 0; i < count; i++) + { + shared_ptr buy = Packet::readItem(stream); + shared_ptr sell = Packet::readItem(stream); + + shared_ptr buyB = nullptr; + if (stream->readBoolean()) + { + buyB = Packet::readItem(stream); + } + bool isDeprecated = stream->readBoolean(); + int uses = stream->readInt(); + int maxUses = stream->readInt(); + + MerchantRecipe *recipe = new MerchantRecipe(buy, buyB, sell, uses, maxUses); + if (isDeprecated) + { + recipe->enforceDeprecated(); + } + list->push_back(recipe); + } + return list; +} + +void MerchantRecipeList::load(CompoundTag *tag) +{ + ListTag *list = (ListTag *) tag->getList(L"Recipes"); + + for (int i = 0; i < list->size(); i++) + { + CompoundTag *recipeTag = list->get(i); + m_recipes.push_back(new MerchantRecipe(recipeTag)); + } +} + +CompoundTag *MerchantRecipeList::createTag() +{ + CompoundTag *tag = new CompoundTag(); + + ListTag *list = new ListTag(L"Recipes"); + for (int i = 0; i < m_recipes.size(); i++) + { + MerchantRecipe *merchantRecipe = m_recipes.at(i); + list->add(merchantRecipe->createTag()); + } + tag->put(L"Recipes", list); + + return tag; +} + +void MerchantRecipeList::push_back(MerchantRecipe *recipe) +{ + m_recipes.push_back(recipe); +} + +MerchantRecipe *MerchantRecipeList::at(size_t index) +{ + return m_recipes.at(index); +} + +std::vector::iterator MerchantRecipeList::begin() +{ + return m_recipes.begin(); +} + +std::vector::iterator MerchantRecipeList::end() +{ + return m_recipes.end(); +} + +std::vector::iterator MerchantRecipeList::erase(std::vector::iterator it) +{ + return m_recipes.erase(it); +} + +size_t MerchantRecipeList::size() +{ + return m_recipes.size(); +} + +bool MerchantRecipeList::empty() +{ + return m_recipes.empty(); +} \ No newline at end of file -- cgit v1.2.3