From e08087b0f66209dd4c9ba0975ce7bd1b5ccb6d6e Mon Sep 17 00:00:00 2001 From: Vincent Date: Tue, 2 Jul 2024 17:40:28 +0100 Subject: [PATCH] feat: dump shapeless recipe data in DevTools --- include/bedrock/world/item/item_descriptor.h | 69 +++++++++++++++++++- include/bedrock/world/item/item_stack_base.h | 5 ++ src/endstone_devtools/vanilla_data.cpp | 17 +++-- 3 files changed, 81 insertions(+), 10 deletions(-) diff --git a/include/bedrock/world/item/item_descriptor.h b/include/bedrock/world/item/item_descriptor.h index 48e83564b..82a04ee9f 100644 --- a/include/bedrock/world/item/item_descriptor.h +++ b/include/bedrock/world/item/item_descriptor.h @@ -14,14 +14,77 @@ #pragma once +#include +#include + +#include "bedrock/deps/jsoncpp/value.h" +#include "bedrock/nbt/compound_tag.h" + +class Item; + class ItemDescriptor { - class BaseDescriptor {}; + enum class InternalType; public: - ItemDescriptor() = default; + struct ItemEntry { + const Item *item; + std::int16_t aux_value; + }; + + class BaseDescriptor { + public: + [[nodiscard]] virtual std::unique_ptr clone() const = 0; + [[nodiscard]] virtual bool sameItems(ItemDescriptor::BaseDescriptor const &, bool) const = 0; + [[nodiscard]] virtual bool sameItem(ItemDescriptor::ItemEntry const &, bool) const = 0; + [[nodiscard]] virtual std::string const &getFullName() const = 0; + [[nodiscard]] virtual ItemDescriptor::ItemEntry getItem() const = 0; + [[nodiscard]] virtual bool forEachItemUntil(std::function func) const = 0; + [[nodiscard]] virtual std::map toMap() const = 0; + [[nodiscard]] virtual std::optional save() const = 0; + virtual void serialize(Json::Value &val) const = 0; + virtual void serialize(BinaryStream &stream) const = 0; + [[nodiscard]] virtual ItemDescriptor::InternalType getType() const = 0; + [[nodiscard]] virtual bool isValid() const = 0; + [[nodiscard]] virtual std::size_t getHash() const = 0; + [[nodiscard]] virtual bool shouldResolve() const = 0; + [[nodiscard]] virtual std::unique_ptr resolve() const = 0; + virtual ~BaseDescriptor() = 0; + }; + ItemDescriptor() = default; virtual ~ItemDescriptor() = default; + [[nodiscard]] std::string const &getFullName() const + { + static std::string empty; + if (!impl_) { + return empty; + } + return impl_->getFullName(); + } + + [[nodiscard]] const Item *getItem() const + { + if (!impl_) { + return nullptr; + } + if (impl_->shouldResolve()) { + impl_ = std::move(impl_->resolve()); + } + return impl_->getItem().item; + } + + [[nodiscard]] std::int16_t getAuxValue() const + { + if (!impl_) { + return 0x7FFF; + } + if (impl_->shouldResolve()) { + impl_ = std::move(impl_->resolve()); + } + return impl_->getItem().aux_value; + } + private: - std::unique_ptr impl_; + mutable std::unique_ptr impl_; }; diff --git a/include/bedrock/world/item/item_stack_base.h b/include/bedrock/world/item/item_stack_base.h index 89e8495dc..47b163e89 100644 --- a/include/bedrock/world/item/item_stack_base.h +++ b/include/bedrock/world/item/item_stack_base.h @@ -105,6 +105,11 @@ class ItemStackBase { return block_; } + [[nodiscard]] std::uint8_t getCount() const // Endstone + { + return count_; + } + private: inline const static std::string TAG_DISPLAY = "display"; // NOLINT(*-identifier-naming) inline const static std::string TAG_DISPLAY_NAME = "Name"; // NOLINT(*-identifier-naming) diff --git a/src/endstone_devtools/vanilla_data.cpp b/src/endstone_devtools/vanilla_data.cpp index 5d759c0cf..41e931879 100644 --- a/src/endstone_devtools/vanilla_data.cpp +++ b/src/endstone_devtools/vanilla_data.cpp @@ -255,24 +255,27 @@ void dumpRecipes(VanillaData &data, ::Level &level) case ShapelessRecipe: { nlohmann::json input; for (const auto &ingredient : entry.recipe->getIngredients()) { - input.push_back({ - // {"id"}, - // {"count"}, - // {"type"}, - // {"auxValue"}, - }); // TODO: ... + nlohmann::json json = { + {"id", ingredient.getFullName()}, + {"count", ingredient.getStackSize()}, + }; + if (ingredient.getAuxValue() != 0x7FFF) { + json["damage"] = ingredient.getAuxValue(); + } + input.push_back(json); } nlohmann::json output; for (const auto &result_item : entry.recipe->getResultItems()) { output.push_back({ {"id", result_item.getItem()->getFullItemName()}, - // {"count", }, // TODO: ... + {"count", result_item.getCount()}, }); } data.recipes.shapeless.push_back({ {"id", entry.recipe->getRecipeId()}, + {"netId", entry.recipe->getNetId().raw_id}, {"input", input}, {"output", output}, {"uuid", entry.recipe->getId().toEndstone().str()},