From 55b5e60b189490c33b415e3c956800da21064e3b Mon Sep 17 00:00:00 2001 From: LaG1924 <12997935+LaG1924@users.noreply.github.com> Date: Wed, 8 Aug 2018 07:30:01 +0500 Subject: Basic BlockState support --- src/AssetManager.cpp | 113 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 80 insertions(+), 33 deletions(-) (limited to 'src/AssetManager.cpp') diff --git a/src/AssetManager.cpp b/src/AssetManager.cpp index aaa71ed..9671491 100644 --- a/src/AssetManager.cpp +++ b/src/AssetManager.cpp @@ -20,6 +20,7 @@ std::map assetIds; std::map blockIdToBlockName; std::unique_ptr assetTree; std::unique_ptr atlas; +std::map blockIdToBlockModel; void LoadIds(); void LoadAssets(); @@ -29,6 +30,7 @@ void WalkDirEntry(const fs::directory_entry &dirEntry, AssetTreeNode *node); void ParseAsset(AssetTreeNode &node); void ParseAssetTexture(AssetTreeNode &node); void ParseAssetBlockModel(AssetTreeNode &node); +void ParseAssetBlockState(AssetTreeNode &node); void ParseBlockModels(); @@ -118,6 +120,11 @@ void ParseAsset(AssetTreeNode &node) { return; } + if (node.parent->name == "blockstates") { + ParseAssetBlockState(node); + return; + } + if (node.data[0] == 0x89 && node.data[1] == 'P' && node.data[2] == 'N' && node.data[3] == 'G') { ParseAssetTexture(node); return; @@ -181,7 +188,7 @@ void ParseAssetBlockModel(AssetTreeNode &node) { model.BlockName = node.name; - if (model.BlockName == "block") + if (model.BlockName == "block" || model.BlockName == "cube_mirrored") model.IsBlock = true; if (model.BlockName == "thin_block" || model.BlockName == "leaves") @@ -291,6 +298,55 @@ void ParseAssetBlockModel(AssetTreeNode &node) { node.data.swap(std::vector()); } +void ParseAssetBlockState(AssetTreeNode &node) { + nlohmann::json j = nlohmann::json::parse(node.data); + + BlockState blockState; + if (j.find("multipart") != j.end()) + return; + + j = j["variants"]; + for (auto variantIt = j.begin(); variantIt != j.end(); variantIt++) { + std::string variantName = variantIt.key(); + BlockStateVariant variant; + variant.variantName = variantName; + if (variantIt.value().is_array()) { + for (auto &it : variantIt.value()) { + BlockStateVariant::Model model; + model.modelName = it["model"].get(); + if (it.count("x")) + model.x = it["x"].get(); + if (it.count("y")) + model.y = it["y"].get(); + if (it.count("uvlock")) + model.uvLock = it["uvlock"].get(); + if (it.count("weight")) + model.weight = it["weight"].get(); + variant.models.push_back(model); + } + } else { + BlockStateVariant::Model model; + model.modelName = variantIt.value()["model"].get(); + if (variantIt.value().count("x")) + model.x = variantIt.value()["x"].get(); + if (variantIt.value().count("y")) + model.y = variantIt.value()["y"].get(); + if (variantIt.value().count("uvlock")) + model.uvLock = variantIt.value()["uvlock"].get(); + if (variantIt.value().count("weight")) + model.weight = variantIt.value()["weight"].get(); + variant.models.push_back(model); + } + blockState.variants[variant.variantName] = variant; + } + + node.asset = std::make_unique(); + AssetBlockState *asset = dynamic_cast(node.asset.get()); + asset->blockState = blockState; + + node.data.swap(std::vector()); +} + void ParseBlockModels() { std::string textureName; @@ -448,40 +504,31 @@ void ParseBlockModels() { } const BlockModel *AssetManager::GetBlockModelByBlockId(BlockId block) { - block.state = 0; - if (blockIdToBlockName.find(block) == blockIdToBlockName.end()) { - std::string blockName = ""; - for (const auto& it : assetIds) { - if (BlockId{ it.second.id,0 } == block) { - blockName = it.first; - break; - } - } - if (blockName == "grass") - blockName = "grass_normal"; - if (blockName == "torch") - blockName = "normal_torch"; - if (blockName == "leaves") - blockName = "oak_leaves"; - if (blockName == "tallgrass") - blockName = "tall_grass"; - if (blockName == "log") - blockName = "oak_bark"; - if (blockName == "snow_layer") - blockName = "snow_height2"; - - blockName = "block/" + blockName; - - if (blockName == "") - return nullptr; - - blockIdToBlockName[block] = blockName; - } + auto it = blockIdToBlockModel.find(block); + if (it != blockIdToBlockModel.end()) + return it->second; + + auto blockStateName = TransformBlockIdToBlockStateName(block); + AssetBlockState *asset = GetAsset("/minecraft/blockstates/" + blockStateName.first); + if (!asset) + return &GetAsset("/minecraft/models/block/error")->blockModel; + + BlockState &blockState = asset->blockState; + if (blockState.variants.find(blockStateName.second) == blockState.variants.end()) + return &GetAsset("/minecraft/models/block/error")->blockModel; + + BlockStateVariant &variant = blockState.variants[blockStateName.second]; + if (variant.models.empty()) + return &GetAsset("/minecraft/models/block/error")->blockModel; + + BlockStateVariant::Model &model = variant.models[0]; + AssetBlockModel *assetModel = GetAsset("/minecraft/models/block/" + model.modelName); + if (!assetModel) + return &GetAsset("/minecraft/models/block/error")->blockModel; - std::string blockName = blockIdToBlockName[block]; + blockIdToBlockModel.insert(std::make_pair(block, &assetModel->blockModel)); - AssetBlockModel *model = GetAsset("/minecraft/models/" + blockName); - return (model == nullptr) ? &GetAsset("/minecraft/models/block/error")->blockModel : &model->blockModel; + return &assetModel->blockModel; } std::string AssetManager::GetAssetNameByBlockId(BlockId block) { -- cgit v1.2.3