4jcraft/Minecraft.World/Containers/MerchantRecipeList.cpp
MatthewBeshay a0fdc643d1 Merge branch 'upstream-dev' into cleanup/nullptr-replacement
# Conflicts:
#	Minecraft.Client/Network/PlayerChunkMap.cpp
#	Minecraft.Client/Network/PlayerList.cpp
#	Minecraft.Client/Network/ServerChunkCache.cpp
#	Minecraft.Client/Platform/Common/Consoles_App.cpp
#	Minecraft.Client/Platform/Common/DLC/DLCManager.cpp
#	Minecraft.Client/Platform/Common/GameRules/LevelGenerationOptions.cpp
#	Minecraft.Client/Platform/Common/GameRules/LevelRuleset.cpp
#	Minecraft.Client/Platform/Common/Tutorial/Tutorial.cpp
#	Minecraft.Client/Platform/Common/Tutorial/TutorialTask.cpp
#	Minecraft.Client/Platform/Common/UI/IUIScene_CreativeMenu.cpp
#	Minecraft.Client/Platform/Common/UI/UIComponent_Panorama.cpp
#	Minecraft.Client/Platform/Common/UI/UIController.cpp
#	Minecraft.Client/Platform/Common/UI/UIController.h
#	Minecraft.Client/Platform/Extrax64Stubs.cpp
#	Minecraft.Client/Platform/Windows64/4JLibs/inc/4J_Input.h
#	Minecraft.Client/Platform/Windows64/4JLibs/inc/4J_Storage.h
#	Minecraft.Client/Player/EntityTracker.cpp
#	Minecraft.Client/Player/ServerPlayer.cpp
#	Minecraft.Client/Rendering/EntityRenderers/PlayerRenderer.cpp
#	Minecraft.Client/Textures/Packs/DLCTexturePack.cpp
#	Minecraft.Client/Textures/Stitching/StitchedTexture.cpp
#	Minecraft.Client/Textures/Stitching/TextureMap.cpp
#	Minecraft.Client/Textures/Textures.cpp
#	Minecraft.World/Blocks/NotGateTile.cpp
#	Minecraft.World/Blocks/PressurePlateTile.cpp
#	Minecraft.World/Blocks/TileEntities/PotionBrewing.cpp
#	Minecraft.World/Enchantments/EnchantmentHelper.cpp
#	Minecraft.World/Entities/HangingEntity.cpp
#	Minecraft.World/Entities/LeashFenceKnotEntity.cpp
#	Minecraft.World/Entities/LivingEntity.cpp
#	Minecraft.World/Entities/Mobs/Boat.cpp
#	Minecraft.World/Entities/Mobs/Minecart.cpp
#	Minecraft.World/Entities/Mobs/Witch.cpp
#	Minecraft.World/Entities/SyncedEntityData.cpp
#	Minecraft.World/Items/LeashItem.cpp
#	Minecraft.World/Items/PotionItem.cpp
#	Minecraft.World/Level/BaseMobSpawner.cpp
#	Minecraft.World/Level/CustomLevelSource.cpp
#	Minecraft.World/Level/Level.cpp
#	Minecraft.World/Level/Storage/DirectoryLevelStorage.cpp
#	Minecraft.World/Level/Storage/McRegionLevelStorage.cpp
#	Minecraft.World/Level/Storage/RegionFileCache.cpp
#	Minecraft.World/Player/Player.cpp
#	Minecraft.World/WorldGen/Biomes/BiomeCache.cpp
#	Minecraft.World/WorldGen/Features/RandomScatteredLargeFeature.cpp
#	Minecraft.World/WorldGen/Layers/BiomeOverrideLayer.cpp
2026-03-30 16:28:40 +11:00

173 lines
5.6 KiB
C++

#include "../Platform/stdafx.h"
#include "../Headers/net.minecraft.world.item.trading.h"
#include "MerchantRecipeList.h"
MerchantRecipeList::MerchantRecipeList() {}
MerchantRecipeList::MerchantRecipeList(CompoundTag* tag) { load(tag); }
MerchantRecipeList::~MerchantRecipeList() {
for (auto it = m_recipes.begin(); it != m_recipes.end(); ++it) {
delete (*it);
}
}
MerchantRecipe* MerchantRecipeList::getRecipeFor(
std::shared_ptr<ItemInstance> buyA, std::shared_ptr<ItemInstance> 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 == nullptr && !r->hasSecondaryBuyItem()) ||
(r->hasSecondaryBuyItem() && buyB != nullptr &&
r->getBuyBItem()->id == buyB->id))) {
if (buyA->count >= r->getBuyAItem()->count &&
(!r->hasSecondaryBuyItem() ||
buyB->count >= r->getBuyBItem()->count)) {
return r;
}
}
return nullptr;
}
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 == nullptr) ||
(r->hasSecondaryBuyItem() && buyB != nullptr &&
r->getBuyBItem()->id == buyB->id &&
buyB->count >= r->getBuyBItem()->count))) {
return r;
}
}
return nullptr;
}
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(
std::shared_ptr<ItemInstance> buy, std::shared_ptr<ItemInstance> buyB,
std::shared_ptr<ItemInstance> 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 != nullptr && buyB->id == r->getBuyBItem()->id &&
buyB->count >= r->getBuyBItem()->count)) {
return r;
}
}
}
return nullptr;
}
void MerchantRecipeList::writeToStream(DataOutputStream* stream) {
stream->writeByte((uint8_t)(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);
std::shared_ptr<ItemInstance> buyBItem = r->getBuyBItem();
stream->writeBoolean(buyBItem != nullptr);
if (buyBItem != nullptr) {
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++) {
std::shared_ptr<ItemInstance> buy = Packet::readItem(stream);
std::shared_ptr<ItemInstance> sell = Packet::readItem(stream);
std::shared_ptr<ItemInstance> 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<CompoundTag>* list =
(ListTag<CompoundTag>*)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<CompoundTag>* list = new ListTag<CompoundTag>(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<MerchantRecipe*>::iterator MerchantRecipeList::begin() {
return m_recipes.begin();
}
std::vector<MerchantRecipe*>::iterator MerchantRecipeList::end() {
return m_recipes.end();
}
std::vector<MerchantRecipe*>::iterator MerchantRecipeList::erase(
std::vector<MerchantRecipe*>::iterator it) {
return m_recipes.erase(it);
}
size_t MerchantRecipeList::size() { return m_recipes.size(); }
bool MerchantRecipeList::empty() { return m_recipes.empty(); }