From d89fadff68a5b32aa0c34dbf75488201d3aa6df0 Mon Sep 17 00:00:00 2001 From: Fireblade <72758695+Firebladedoge229@users.noreply.github.com> Date: Sat, 2 May 2026 15:14:48 -0400 Subject: [PATCH] feat: blockstates still a work in progress --- .../Common/UI/UIScene_InventoryMenu.cpp | 2 +- Minecraft.Client/Gui.cpp | 94 +++ Minecraft.World/BlockStateDecoder.cpp | 671 ++++++++++++++++++ Minecraft.World/BlockStateDecoder.h | 19 + Minecraft.World/BlockStateDecoderRegistry.cpp | 35 + Minecraft.World/BlockStateDecoderRegistry.h | 12 + Minecraft.World/BrewingStandTile.cpp | 26 + Minecraft.World/BrewingStandTile.h | 5 + Minecraft.World/ButtonTile.cpp | 26 + Minecraft.World/ButtonTile.h | 5 + Minecraft.World/CMakeLists.txt | 5 + Minecraft.World/CactusTile.cpp | 26 + Minecraft.World/CactusTile.h | 5 + Minecraft.World/CocoaTile.cpp | 26 + Minecraft.World/CocoaTile.h | 5 + Minecraft.World/CropTile.cpp | 26 + Minecraft.World/CropTile.h | 5 + Minecraft.World/DoorTile.cpp | 82 +++ Minecraft.World/DoorTile.h | 11 + Minecraft.World/FenceGateTile.cpp | 26 + Minecraft.World/FenceGateTile.h | 5 + Minecraft.World/FenceTile.cpp | 31 + Minecraft.World/FenceTile.h | 5 + Minecraft.World/FireTile.cpp | 35 + Minecraft.World/FireTile.h | 11 + Minecraft.World/FlowerPotTile.cpp | 26 + Minecraft.World/FlowerPotTile.h | 5 + Minecraft.World/HalfSlabTile.cpp | 26 + Minecraft.World/HalfSlabTile.h | 6 + Minecraft.World/HayBlockTile.cpp | 25 + Minecraft.World/HayBlockTile.h | 5 + Minecraft.World/HopperTile.cpp | 26 + Minecraft.World/HopperTile.h | 6 + Minecraft.World/HugeMushroomTile.cpp | 26 + Minecraft.World/HugeMushroomTile.h | 5 + Minecraft.World/JukeboxTile.cpp | 26 + Minecraft.World/JukeboxTile.h | 5 + Minecraft.World/LeverTile.cpp | 26 + Minecraft.World/LeverTile.h | 5 + Minecraft.World/NetherStalkTile.cpp | 26 + Minecraft.World/NetherStalkTile.h | 5 + Minecraft.World/NetherWartTile.cpp | 26 + Minecraft.World/NetherWartTile.h | 5 + Minecraft.World/PistonBaseTile.cpp | 26 + Minecraft.World/PistonBaseTile.h | 5 + Minecraft.World/PistonExtensionTile.cpp | 26 + Minecraft.World/PistonExtensionTile.h | 5 + Minecraft.World/ReedTile.cpp | 26 + Minecraft.World/ReedTile.h | 5 + Minecraft.World/RepeaterTile.cpp | 26 + Minecraft.World/RepeaterTile.h | 6 + Minecraft.World/RotatedPillarTile.cpp | 26 + Minecraft.World/RotatedPillarTile.h | 5 + Minecraft.World/Sapling.cpp | 26 + Minecraft.World/Sapling.h | 5 + Minecraft.World/StairTile.cpp | 186 +++++ Minecraft.World/StairTile.h | 9 + Minecraft.World/StemTile.cpp | 29 + Minecraft.World/StemTile.h | 5 + Minecraft.World/TallGrass.cpp | 26 + Minecraft.World/TallGrass.h | 5 + Minecraft.World/TallGrass2.cpp | 26 + Minecraft.World/TallGrass2.h | 5 + Minecraft.World/TheEndPortalFrameTile.cpp | 26 + Minecraft.World/TheEndPortalFrameTile.h | 5 + Minecraft.World/Tile.cpp | 42 ++ Minecraft.World/Tile.h | 27 + Minecraft.World/TrapDoorTile.cpp | 26 + Minecraft.World/TrapDoorTile.h | 5 + Minecraft.World/TreeTile.cpp | 26 + Minecraft.World/TreeTile.h | 5 + Minecraft.World/TreeTile2.cpp | 26 + Minecraft.World/TreeTile2.h | 5 + Minecraft.World/TripWireSourceTile.cpp | 26 + Minecraft.World/TripWireSourceTile.h | 5 + Minecraft.World/TripWireTile.cpp | 32 + Minecraft.World/TripWireTile.h | 5 + Minecraft.World/VineTile.cpp | 26 + Minecraft.World/VineTile.h | 5 + build-linux.sh | 2 +- 80 files changed, 2249 insertions(+), 2 deletions(-) create mode 100644 Minecraft.World/BlockStateDecoder.cpp create mode 100644 Minecraft.World/BlockStateDecoder.h create mode 100644 Minecraft.World/BlockStateDecoderRegistry.cpp create mode 100644 Minecraft.World/BlockStateDecoderRegistry.h diff --git a/Minecraft.Client/Common/UI/UIScene_InventoryMenu.cpp b/Minecraft.Client/Common/UI/UIScene_InventoryMenu.cpp index fe0add7d..9031cb92 100644 --- a/Minecraft.Client/Common/UI/UIScene_InventoryMenu.cpp +++ b/Minecraft.Client/Common/UI/UIScene_InventoryMenu.cpp @@ -6,7 +6,7 @@ #include "..\..\..\Minecraft.World\net.minecraft.world.item.h" #include "..\..\..\Minecraft.World\net.minecraft.stats.h" #include "..\..\..\Minecraft.World\net.minecraft.world.effect.h" -#include "..\..\MultiplayerLocalPlayer.h" +#include "..\..\MultiPlayerLocalPlayer.h" #include "..\..\Minecraft.h" #include "..\..\Options.h" #include "..\..\EntityRenderDispatcher.h" diff --git a/Minecraft.Client/Gui.cpp b/Minecraft.Client/Gui.cpp index 8c30b1ff..98c7d691 100644 --- a/Minecraft.Client/Gui.cpp +++ b/Minecraft.Client/Gui.cpp @@ -28,7 +28,13 @@ #include "../Minecraft.World/net.minecraft.world.h" #include "../Minecraft.World/LevelChunk.h" #include "../Minecraft.World/Biome.h" +#include "../Minecraft.World/HitResult.h" #include +#include "../Minecraft.World/Tile.h" +#include "../Minecraft.World/BlockStateDecoderRegistry.h" +#include "../Minecraft.World/BlockStateDecoder.h" +#include +#include ResourceLocation Gui::PUMPKIN_BLUR_LOCATION = ResourceLocation(TN__BLUR__MISC_PUMPKINBLUR); @@ -1157,6 +1163,94 @@ void Gui::render(float a, bool mouseFree, int xMouse, int yMouse) lines.push_back(L"Facing: " + std::wstring(cardinals[direction]) + L" (" + angleString + L")"); // We have to limit y to 256 as we don't get any information past that + // target block state + if (minecraft->hitResult != nullptr && minecraft->hitResult->type == HitResult::TILE) + { + int hx = minecraft->hitResult->x; + int hy = minecraft->hitResult->y; + int hz = minecraft->hitResult->z; + if (minecraft->level != NULL && minecraft->level->hasChunkAt(hx, hy, hz)) + { + int tid = minecraft->level->getTile(hx, hy, hz); + if (tid >= 0 && tid < Tile::TILE_NUM_COUNT) + { + Tile *t = Tile::tiles[tid]; + if (t != nullptr) + { + Tile::BlockState st = t->getBlockState(minecraft->level, hx, hy, hz); + // check registry so we dont end up with random integers + std::wstring decoded = BlockStateDecoderRegistry::decode(tid, st.value); + + if (decoded.empty()) { + if (tid == Tile::door_wood_Id || tid == Tile::door_iron_Id || tid == Tile::spruce_door_Id || tid == Tile::birch_door_Id || tid == Tile::jungle_door_Id || tid == Tile::acacia_door_Id || tid == Tile::dark_oak_door_Id) { + decoded = BlockStateDecoder::doorPropsToString(BlockStateDecoder::decodeDoor(st.value)); + } + } + + if (!decoded.empty()) + { + std::map props; + size_t start = 0; + while (start < decoded.size()) { + size_t pos = decoded.find(L'\n', start); + std::wstring line = (pos == std::wstring::npos) ? decoded.substr(start) : decoded.substr(start, pos - start); + size_t colon = line.find(L':'); + if (colon != std::wstring::npos) { + std::wstring key = line.substr(0, colon); + std::wstring val = line.substr(colon + 1); + auto trim = [](std::wstring &s) { + size_t i = 0; + while (i < s.size() && iswspace(s[i])) ++i; + if (i) s.erase(0, i); + // right + if (!s.empty()) { + size_t j = s.size() - 1; + while (j != (size_t)-1 && iswspace(s[j])) --j; + s.erase(j + 1); + } + }; + trim(key); + trim(val); + props[key] = val; + } + if (pos == std::wstring::npos) break; + start = pos + 1; + } + lines.push_back(L"State:"); + if (props.find(L"age") != props.end()) lines.push_back(L"age: " + props[L"age"]); + if (props.find(L"facing") != props.end()) lines.push_back(L"facing: " + props[L"facing"]); + if (props.find(L"north") != props.end()) lines.push_back(L"north: " + props[L"north"]); + if (props.find(L"south") != props.end()) lines.push_back(L"south: " + props[L"south"]); + if (props.find(L"east") != props.end()) lines.push_back(L"east: " + props[L"east"]); + if (props.find(L"west") != props.end()) lines.push_back(L"west: " + props[L"west"]); + if (props.find(L"type") != props.end()) lines.push_back(L"type: " + props[L"type"]); + if (props.find(L"variant") != props.end()) lines.push_back(L"variant: " + props[L"variant"]); + if (props.find(L"axis") != props.end()) lines.push_back(L"axis: " + props[L"axis"]); + if (props.find(L"facing") != props.end()) lines.push_back(L"facing: " + props[L"facing"]); + if (props.find(L"hinge") != props.end()) lines.push_back(L"hinge: " + props[L"hinge"]); + if (props.find(L"half") != props.end()) lines.push_back(L"half: " + props[L"half"]); + if (props.find(L"shape") != props.end()) lines.push_back(L"shape: " + props[L"shape"]); + if (props.find(L"up") != props.end()) lines.push_back(L"up: " + props[L"up"]); + if (props.find(L"extended") != props.end()) lines.push_back(L"extended: " + props[L"extended"]); + if (props.find(L"open") != props.end()) lines.push_back(L"open: " + props[L"open"]); + if (props.find(L"attached") != props.end()) lines.push_back(L"attached: " + props[L"attached"]); + if (props.find(L"powered") != props.end()) lines.push_back(L"powered: " + props[L"powered"]); + if (props.find(L"delay") != props.end()) lines.push_back(L"delay: " + props[L"delay"]); + if (props.find(L"enabled") != props.end()) lines.push_back(L"enabled: " + props[L"enabled"]); + if (props.find(L"eye") != props.end()) lines.push_back(L"eye: " + props[L"eye"]); + if (props.find(L"bottle_0") != props.end()) lines.push_back(L"bottle_0: " + props[L"bottle_0"]); + if (props.find(L"bottle_1") != props.end()) lines.push_back(L"bottle_1: " + props[L"bottle_1"]); + if (props.find(L"bottle_2") != props.end()) lines.push_back(L"bottle_2: " + props[L"bottle_2"]); + if (props.find(L"has_record") != props.end()) lines.push_back(L"has_record: " + props[L"has_record"]); + } + else + { + lines.push_back(L"Target BlockState: " + std::to_wstring(st.value)); + } + } + } + } + } if (minecraft->level != NULL && minecraft->level->hasChunkAt(xBlockPos, fmod(yBlockPos, 256), zBlockPos)) { LevelChunk *chunkAt = minecraft->level->getChunkAt(xBlockPos, zBlockPos); diff --git a/Minecraft.World/BlockStateDecoder.cpp b/Minecraft.World/BlockStateDecoder.cpp new file mode 100644 index 00000000..986a655c --- /dev/null +++ b/Minecraft.World/BlockStateDecoder.cpp @@ -0,0 +1,671 @@ +#include "BlockStateDecoder.h" +#include "BlockStateDecoderRegistry.h" + +#include "CocoaTile.h" +#include "DirectionalTile.h" +#include "Direction.h" +#include "FireTile.h" +#include "ButtonTile.h" +#include "CropTile.h" +#include "FenceGateTile.h" +#include "FenceTile.h" +#include "DoorTile.h" +#include "FlowerPotTile.h" +#include "HalfSlabTile.h" +#include "HayBlockTile.h" +#include "HugeMushroomTile.h" +#include "HopperTile.h" +#include "BrewingStandTile.h" +#include "PistonBaseTile.h" +#include "PistonExtensionTile.h" +#include "LeverTile.h" +#include "TorchTile.h" +#include "FurnaceTile.h" +#include "RedStoneOreTile.h" +#include "NotGateTile.h" +#include "RedlightTile.h" +#include "JukeboxTile.h" +#include "NetherStalkTile.h" +#include "ReedTile.h" +#include "RepeaterTile.h" +#include "Sapling.h" +#include "StoneSlabTile.h" +#include "StoneSlabTile2.h" +#include "StairTile.h" +#include "StemTile.h" +#include "TreeTile.h" +#include "TreeTile2.h" +#include "TheEndPortalFrameTile.h" +#include "TrapDoorTile.h" +#include "WoodSlabTile.h" +#include "TallGrass.h" +#include "TallGrass2.h" +#include "VineTile.h" +#include "Facing.h" + +#include + +using namespace BlockStateDecoder; + +DoorProps BlockStateDecoder::decodeDoor(int composite) +{ + DoorProps p; + p.dir = composite & DoorTile::C_DIR_MASK; + static const std::wstring dirNames[] = { L"south", L"west", L"north", L"east" }; + if (p.dir >= 0 && p.dir < 4) p.dirName = dirNames[p.dir]; else p.dirName = L"unknown"; + p.open = (composite & DoorTile::C_OPEN_MASK) != 0; + p.upper = (composite & DoorTile::C_IS_UPPER_MASK) != 0; + p.hingeRight = (composite & DoorTile::C_RIGHT_HINGE_MASK) != 0; + return p; +} + +std::wstring BlockStateDecoder::doorPropsToString(const DoorProps &p) +{ + std::wstringstream ss; + ss << L"facing: " << p.dirName << L"\n"; + ss << L"open: " << (p.open ? L"true" : L"false") << L"\n"; + ss << L"half: " << (p.upper ? L"upper" : L"lower") << L"\n"; + ss << L"hinge: " << (p.hingeRight ? L"right" : L"left"); + return ss.str(); +} + +static std::wstring agePropsToString(int age) +{ + std::wstringstream ss; + ss << L"age: " << age; + return ss.str(); +} + +static std::wstring cocoaPropsToString(int composite) +{ + int dir = composite & 0x3; + int age = (composite >> 2) & 0x3; + static const std::wstring dirNames[] = { L"south", L"west", L"north", L"east" }; + std::wstring facing = (dir >= 0 && dir < 4) ? dirNames[dir] : L"unknown"; + std::wstringstream ss; + ss << L"facing: " << facing << L"\n"; + ss << L"age: " << age; + return ss.str(); +} + +static std::wstring stemPropsToString(int composite) +{ + int age = composite & 0x7; + int facingCode = (composite >> 3) & 0x7; + static const std::wstring facingNames[] = { L"none", L"west", L"east", L"north", L"south" }; + std::wstring facing = (facingCode >= 0 && facingCode < 5) ? facingNames[facingCode] : L"unknown"; + std::wstringstream ss; + ss << L"age: " << age << L"\n"; + ss << L"facing: " << facing; + return ss.str(); +} + +static std::wstring vinePropsToString(int composite) +{ + std::wstringstream ss; + ss << L"north: " << (((composite & VineTile::VINE_NORTH) != 0) ? L"true" : L"false") << L"\n"; + ss << L"south: " << (((composite & VineTile::VINE_SOUTH) != 0) ? L"true" : L"false") << L"\n"; + ss << L"east: " << (((composite & VineTile::VINE_EAST) != 0) ? L"true" : L"false") << L"\n"; + ss << L"west: " << (((composite & VineTile::VINE_WEST) != 0) ? L"true" : L"false"); + return ss.str(); +} + +static std::wstring flowerPotTypeToString(int type) +{ + switch (type) + { + case FlowerPotTile::TYPE_FLOWER_RED: return L"red_flower"; + case FlowerPotTile::TYPE_FLOWER_YELLOW: return L"yellow_flower"; + case FlowerPotTile::TYPE_SAPLING_DEFAULT: return L"sapling_default"; + case FlowerPotTile::TYPE_SAPLING_EVERGREEN: return L"sapling_evergreen"; + case FlowerPotTile::TYPE_SAPLING_BIRCH: return L"sapling_birch"; + case FlowerPotTile::TYPE_SAPLING_JUNGLE: return L"sapling_jungle"; + case FlowerPotTile::TYPE_MUSHROOM_RED: return L"red_mushroom"; + case FlowerPotTile::TYPE_MUSHROOM_BROWN: return L"brown_mushroom"; + case FlowerPotTile::TYPE_CACTUS: return L"cactus"; + case FlowerPotTile::TYPE_DEAD_BUSH: return L"dead_bush"; + case FlowerPotTile::TYPE_FERN: return L"fern"; + default: return L"empty"; + } +} + +static std::wstring flowerPotPropsToString(int composite) +{ + std::wstringstream ss; + ss << L"type: " << flowerPotTypeToString(composite & 0xF); + return ss.str(); +} + +static std::wstring saplingPropsToString(int composite) +{ + int type = composite & 0x7; + bool grown = (composite & 0x8) != 0; + static const std::wstring typeNames[] = { L"oak", L"spruce", L"birch", L"jungle", L"acacia", L"dark_oak" }; + std::wstring typeName = (type >= 0 && type < 6) ? typeNames[type] : L"unknown"; + std::wstringstream ss; + ss << L"type: " << typeName << L"\n"; + ss << L"age: " << (grown ? 1 : 0); + return ss.str(); +} + +static std::wstring tallGrassPropsToString(int composite) +{ + int type = composite & 0x3; + static const std::wstring typeNames[] = { L"dead_shrub", L"tall_grass", L"fern" }; + std::wstring typeName = (type >= 0 && type < 3) ? typeNames[type] : L"unknown"; + std::wstringstream ss; + ss << L"type: " << typeName; + return ss.str(); +} + +static std::wstring tallGrass2PropsToString(int composite) +{ + int type = composite & 0x7; + bool upper = (composite & TallGrass2::UPPER_BIT) != 0; + static const std::wstring typeNames[] = { L"sunflower", L"lilac", L"tall_grass", L"large_fern", L"rose_bush", L"peony" }; + std::wstring typeName = (type >= 0 && type < TallGrass2::VARIANT_COUNT) ? typeNames[type] : L"unknown"; + std::wstringstream ss; + ss << L"type: " << typeName << L"\n"; + ss << L"half: " << (upper ? L"upper" : L"lower"); + return ss.str(); +} + +static std::wstring brewingStandPropsToString(int composite) +{ + std::wstringstream ss; + ss << L"bottle_0: " << (((composite & 0x1) != 0) ? L"true" : L"false") << L"\n"; + ss << L"bottle_1: " << (((composite & 0x2) != 0) ? L"true" : L"false") << L"\n"; + ss << L"bottle_2: " << (((composite & 0x4) != 0) ? L"true" : L"false"); + return ss.str(); +} + +static std::wstring jukeboxPropsToString(int composite) +{ + std::wstringstream ss; + ss << L"has_record: " << (((composite & 0x1) != 0) ? L"true" : L"false"); + return ss.str(); +} + +static std::wstring daylightDetectorPropsToString(int composite) +{ + std::wstringstream ss; + ss << L"power: " << (composite & 0xF); + return ss.str(); +} + +static std::wstring snowPropsToString(int composite) +{ + std::wstringstream ss; + int layers = (composite & 0x7) + 1; + ss << L"layers: " << layers; + return ss.str(); +} + +static std::wstring cauldronPropsToString(int composite) +{ + std::wstringstream ss; + int level = composite & 0x3; + ss << L"level: " << level; + return ss.str(); +} + +static std::wstring firePropsToString(int composite) { + +} + +static std::wstring torchPropsToString(int composite) +{ +int dir = composite & 0x7; +static const std::wstring dirNames[] = { L"up", L"west", L"east", L"south", L"north", L"unknown" }; +std::wstring dirName = (dir >= 0 && dir < 6) ? dirNames[dir > 4 ? 5 : dir] : L"unknown"; +std::wstringstream ss; +ss << L"facing: " << dirName; +return ss.str(); +} + +static std::wstring furnacePropsToString(int composite) +{ +int facing = composite & 0x7; +static const std::wstring facingNames[] = { L"unknown", L"unknown", L"north", L"south", L"west", L"east" }; +std::wstring facingName = (facing >= 2 && facing <= 5) ? facingNames[facing] : L"unknown"; +std::wstringstream ss; +ss << L"facing: " << facingName; +return ss.str(); +} + +static std::wstring redstoneOrePropsToString(int composite) +{ +std::wstringstream ss; +ss << L"lit: " << (((composite & 0x1) != 0) ? L"true" : L"false"); +return ss.str(); +} + +static std::wstring redstoneTorchPropsToString(int composite) +{ +int dir = composite & 0x7; +static const std::wstring dirNames[] = { L"up", L"west", L"east", L"south", L"north", L"unknown" }; +std::wstring dirName = (dir >= 0 && dir < 6) ? dirNames[dir > 4 ? 5 : dir] : L"unknown"; +std::wstringstream ss; +ss << L"facing: " << dirName; +return ss.str(); +} + +static std::wstring redlightPropsToString(int composite) +{ + std::wstringstream ss; + ss << L"lit: " << (((composite & 0x1) != 0) ? L"true" : L"false"); + return ss.str(); +} + +static std::wstring buttonFacingToString(int data) +{ + switch (data & 0x7) + { + case 1: return L"east"; + case 2: return L"west"; + case 3: return L"south"; + case 4: return L"north"; + case 5: return L"ceiling"; + case 6: return L"floor"; + default: return L"unknown"; + } +} + +static std::wstring buttonPropsToString(int composite) +{ + std::wstringstream ss; + ss << L"facing: " << buttonFacingToString(composite) << L"\n"; + ss << L"powered: " << (((composite & 0x8) != 0) ? L"true" : L"false"); + return ss.str(); +} + +static std::wstring leverFacingToString(int data) +{ + static const std::wstring names[] = { + L"down_south", L"down_east", L"down_west", L"down_north", + L"up_south", L"up_north", L"ceiling_west", L"ceiling_east" + }; + int facing = data & 7; + return (facing >= 0 && facing < 8) ? names[facing] : L"unknown"; +} + +static std::wstring leverPropsToString(int composite) +{ + std::wstringstream ss; + ss << L"facing: " << leverFacingToString(composite) << L"\n"; + ss << L"powered: " << (((composite & 0x8) != 0) ? L"true" : L"false"); + return ss.str(); +} + +static std::wstring fenceGatePropsToString(int composite) +{ + int dir = DirectionalTile::getDirection(composite); + static const std::wstring dirNames[] = { L"south", L"west", L"north", L"east" }; + std::wstring facing = (dir >= 0 && dir < 4) ? dirNames[dir] : L"unknown"; + std::wstringstream ss; + ss << L"facing: " << facing << L"\n"; + ss << L"open: " << (FenceGateTile::isOpen(composite) ? L"true" : L"false"); + return ss.str(); +} + +static std::wstring slabTypeToString(int tileId, int type) +{ + if (tileId == Tile::woodSlab_Id || tileId == Tile::woodSlabHalf_Id) + { + static const std::wstring typeNames[] = { L"oak", L"spruce", L"birch", L"jungle", L"acacia", L"dark_oak" }; + return (type >= 0 && type < 6) ? typeNames[type] : L"unknown"; + } + + if (tileId == Tile::stone_slab2_Id || tileId == Tile::double_stone_slab2_Id) + { + return (type == StoneSlabTile2::RED_SANDSTONE_SLAB) ? L"red_sandstone" : L"unknown"; + } + + static const std::wstring typeNames[] = { + L"stone", L"sandstone", L"wood", L"cobblestone", + L"brick", L"stone_brick", L"nether_brick", L"quartz" + }; + return (type >= 0 && type < 8) ? typeNames[type] : L"unknown"; +} + +static std::wstring slabPropsToString(int tileId, int composite) +{ + int type = composite & HalfSlabTile::TYPE_MASK; + bool top = (composite & HalfSlabTile::TOP_SLOT_BIT) != 0; + std::wstringstream ss; + ss << L"type: " << slabTypeToString(tileId, type); + if (tileId == Tile::woodSlabHalf_Id || tileId == Tile::stoneSlabHalf_Id || tileId == Tile::stone_slab2_Id) + { + ss << L"\n"; + ss << L"half: " << (top ? L"top" : L"bottom"); + } + else + { + ss << L"\n"; + ss << L"half: double"; + } + return ss.str(); +} + +static std::wstring trapDoorPropsToString(int composite) +{ + int dir = composite & 0x3; + static const std::wstring dirNames[] = { L"north", L"south", L"west", L"east" }; + std::wstring facing = (dir >= 0 && dir < 4) ? dirNames[dir] : L"unknown"; + bool open = (composite & 0x4) != 0; + bool top = (composite & 0x8) != 0; + + std::wstringstream ss; + ss << L"facing: " << facing << L"\n"; + ss << L"open: " << (open ? L"true" : L"false") << L"\n"; + ss << L"half: " << (top ? L"top" : L"bottom"); + return ss.str(); +} + +static std::wstring fencePropsToString(int composite) +{ + std::wstringstream ss; + ss << L"north: " << (((composite & 0x1) != 0) ? L"true" : L"false") << L"\n"; + ss << L"south: " << (((composite & 0x2) != 0) ? L"true" : L"false") << L"\n"; + ss << L"east: " << (((composite & 0x4) != 0) ? L"true" : L"false") << L"\n"; + ss << L"west: " << (((composite & 0x8) != 0) ? L"true" : L"false"); + return ss.str(); +} + +static std::wstring axisToString(int composite) +{ + switch (composite & RotatedPillarTile::MASK_FACING) + { + case RotatedPillarTile::FACING_X: return L"x"; + case RotatedPillarTile::FACING_Z: return L"z"; + default: return L"y"; + } +} + +static std::wstring hayBlockPropsToString(int composite) +{ + std::wstringstream ss; + ss << L"axis: " << axisToString(composite); + return ss.str(); +} + +static std::wstring facingToString(int facing) +{ + static const std::wstring facingNames[] = { L"down", L"up", L"north", L"south", L"west", L"east" }; + return (facing >= 0 && facing < 6) ? facingNames[facing] : L"unknown"; +} + +static std::wstring pistonBasePropsToString(int composite) +{ + int facing = PistonBaseTile::getFacing(composite); + std::wstringstream ss; + ss << L"facing: " << facingToString(facing) << L"\n"; + ss << L"extended: " << (PistonBaseTile::isExtended(composite) ? L"true" : L"false"); + return ss.str(); +} + +static std::wstring pistonExtensionPropsToString(int composite) +{ + int facing = PistonExtensionTile::getFacing(composite); + std::wstringstream ss; + ss << L"facing: " << facingToString(facing) << L"\n"; + ss << L"type: " << (((composite & PistonExtensionTile::STICKY_BIT) != 0) ? L"sticky" : L"normal"); + return ss.str(); +} + +static std::wstring endPortalFramePropsToString(int composite) +{ + static const std::wstring dirNames[] = { L"south", L"west", L"north", L"east" }; + int facing = composite & 0x3; + std::wstring facingName = (facing >= 0 && facing < 4) ? dirNames[facing] : L"unknown"; + std::wstringstream ss; + ss << L"facing: " << facingName << L"\n"; + ss << L"eye: " << ((composite & TheEndPortalFrameTile::EYE_BIT) != 0 ? L"true" : L"false"); + return ss.str(); +} + +static std::wstring repeaterPropsToString(int composite, bool powered) +{ + int dir = DirectionalTile::getDirection(composite); + static const std::wstring dirNames[] = { L"south", L"west", L"north", L"east" }; + std::wstring facing = (dir >= 0 && dir < 4) ? dirNames[dir] : L"unknown"; + int delay = ((composite & RepeaterTile::DELAY_MASK) >> RepeaterTile::DELAY_SHIFT) + 1; + + std::wstringstream ss; + ss << L"facing: " << facing << L"\n"; + ss << L"delay: " << delay << L"\n"; + ss << L"powered: " << (powered ? L"true" : L"false"); + return ss.str(); +} + +static std::wstring hugeMushroomPropsToString(int composite) +{ + std::wstringstream ss; + ss << L"variant: " << (composite & 0xF); + return ss.str(); +} + +static std::wstring hopperPropsToString(int composite) +{ + int face = HopperTile::getAttachedFace(composite); + static const std::wstring faceNames[] = { L"down", L"up", L"north", L"south", L"west", L"east" }; + std::wstring facing = (face >= 0 && face < 6) ? faceNames[face] : L"unknown"; + bool enabled = HopperTile::isTurnedOn(composite); + + std::wstringstream ss; + ss << L"facing: " << facing << L"\n"; + ss << L"enabled: " << (enabled ? L"true" : L"false"); + return ss.str(); +} + +static std::wstring logBlockPropsToString(int tileId, int composite) +{ + int type = composite & RotatedPillarTile::MASK_TYPE; + std::wstring axis = axisToString(composite); + std::wstring typeName; + + if (tileId == Tile::treeTrunk_Id) + { + static const std::wstring typeNames[] = { L"oak", L"spruce", L"birch", L"jungle" }; + typeName = (type >= 0 && type < 4) ? typeNames[type] : L"unknown"; + } + else + { + static const std::wstring typeNames[] = { L"acacia", L"dark_oak" }; + typeName = (type >= 0 && type < 2) ? typeNames[type] : L"unknown"; + } + + std::wstringstream ss; + ss << L"type: " << typeName << L"\n"; + ss << L"axis: " << axis; + return ss.str(); +} + +static std::wstring tripWirePropsToString(int composite) +{ + std::wstringstream ss; + ss << L"north: " << (((composite & 0x1) != 0) ? L"true" : L"false") << L"\n"; + ss << L"south: " << (((composite & 0x2) != 0) ? L"true" : L"false") << L"\n"; + ss << L"east: " << (((composite & 0x4) != 0) ? L"true" : L"false") << L"\n"; + ss << L"west: " << (((composite & 0x8) != 0) ? L"true" : L"false"); + return ss.str(); +} + +static std::wstring tripWireSourcePropsToString(int composite) +{ + int dir = composite & 0x3; + static const std::wstring dirNames[] = { L"north", L"east", L"south", L"west" }; + std::wstring facing = (dir >= 0 && dir < 4) ? dirNames[dir] : L"unknown"; + bool attached = (composite & 0x4) != 0; + bool powered = (composite & 0x8) != 0; + + std::wstringstream ss; + ss << L"facing: " << facing << L"\n"; + ss << L"attached: " << (attached ? L"true" : L"false") << L"\n"; + ss << L"powered: " << (powered ? L"true" : L"false"); + return ss.str(); +} + +static bool registerDoorDecoder() +{ + using namespace BlockStateDecoderRegistry; + DecoderFn fn = [](int composite)->std::wstring { + return BlockStateDecoder::doorPropsToString(BlockStateDecoder::decodeDoor(composite)); + }; + registerDecoder(Tile::door_wood_Id, fn); + registerDecoder(Tile::door_iron_Id, fn); + registerDecoder(Tile::spruce_door_Id, fn); + registerDecoder(Tile::birch_door_Id, fn); + registerDecoder(Tile::jungle_door_Id, fn); + registerDecoder(Tile::acacia_door_Id, fn); + registerDecoder(Tile::dark_oak_door_Id, fn); + return true; +registerDecoder(Tile::torch_Id, [](int composite)->std::wstring { return torchPropsToString(composite); }); +registerDecoder(Tile::furnace_Id, [](int composite)->std::wstring { return furnacePropsToString(composite); }); +registerDecoder(Tile::furnace_lit_Id, [](int composite)->std::wstring { return furnacePropsToString(composite); }); +registerDecoder(Tile::redStoneOre_Id, [](int composite)->std::wstring { return redstoneOrePropsToString(composite); }); +registerDecoder(Tile::redStoneOre_lit_Id, [](int composite)->std::wstring { return redstoneOrePropsToString(composite); }); +registerDecoder(Tile::redstoneTorch_off_Id, [](int composite)->std::wstring { return redstoneTorchPropsToString(composite); }); +registerDecoder(Tile::redstoneTorch_on_Id, [](int composite)->std::wstring { return redstoneTorchPropsToString(composite); }); +registerDecoder(Tile::redstoneLight_Id, [](int composite)->std::wstring { return redlightPropsToString(composite); }); +registerDecoder(Tile::redstoneLight_lit_Id, [](int composite)->std::wstring { return redlightPropsToString(composite); }); +} + +static bool s_doorDecoderRegistered = registerDoorDecoder(); + +static bool registerStairDecoder() +{ + using namespace BlockStateDecoderRegistry; + DecoderFn fn = [](int composite)->std::wstring { + int dir = composite & 0x3; + static const std::wstring dirNames[] = { L"east", L"west", L"south", L"north" }; + std::wstring facing = (dir >= 0 && dir < 4) ? dirNames[dir] : L"unknown"; + bool upside = (composite & StairTile::UPSIDEDOWN_BIT) != 0; + int shape = (composite >> 3) & 0x7; + std::wstring shapeName = L"straight"; + if (shape == 1) shapeName = L"inner"; + else if (shape == 2) shapeName = L"outer"; + + std::wstringstream ss; + ss << L"facing: " << facing << L"\n"; + ss << L"half: " << (upside ? L"top" : L"bottom") << L"\n"; + ss << L"shape: " << shapeName; + return ss.str(); + }; + + registerDecoder(Tile::stairs_wood_Id, fn); + registerDecoder(Tile::stairs_stone_Id, fn); + registerDecoder(Tile::stairs_bricks_Id, fn); + registerDecoder(Tile::stairs_stoneBrick_Id, fn); + registerDecoder(Tile::stairs_netherBricks_Id, fn); + registerDecoder(Tile::stairs_sandstone_Id, fn); + registerDecoder(Tile::stairs_sprucewood_Id, fn); + registerDecoder(Tile::stairs_birchwood_Id, fn); + registerDecoder(Tile::stairs_junglewood_Id, fn); + registerDecoder(Tile::stairs_quartz_Id, fn); + registerDecoder(Tile::stairs_acaciawood_Id, fn); + registerDecoder(Tile::stairs_darkwood_Id, fn); + registerDecoder(Tile::stairs_red_sandstone_Id, fn); + return true; +registerDecoder(Tile::torch_Id, [](int composite)->std::wstring { return torchPropsToString(composite); }); +registerDecoder(Tile::furnace_Id, [](int composite)->std::wstring { return furnacePropsToString(composite); }); +registerDecoder(Tile::furnace_lit_Id, [](int composite)->std::wstring { return furnacePropsToString(composite); }); +registerDecoder(Tile::redStoneOre_Id, [](int composite)->std::wstring { return redstoneOrePropsToString(composite); }); +registerDecoder(Tile::redStoneOre_lit_Id, [](int composite)->std::wstring { return redstoneOrePropsToString(composite); }); +registerDecoder(Tile::redstoneTorch_off_Id, [](int composite)->std::wstring { return redstoneTorchPropsToString(composite); }); +registerDecoder(Tile::redstoneTorch_on_Id, [](int composite)->std::wstring { return redstoneTorchPropsToString(composite); }); +registerDecoder(Tile::redstoneLight_Id, [](int composite)->std::wstring { return redlightPropsToString(composite); }); +registerDecoder(Tile::redstoneLight_lit_Id, [](int composite)->std::wstring { return redlightPropsToString(composite); }); +} + +static bool s_stairDecoderRegistered = registerStairDecoder(); + +static bool registerPlantDecoders() +{ + using namespace BlockStateDecoderRegistry; + DecoderFn ageDecoder = [](int composite)->std::wstring { + return agePropsToString(composite); + }; + + registerDecoder(Tile::wheat_Id, ageDecoder); + registerDecoder(Tile::carrots_Id, ageDecoder); + registerDecoder(Tile::potatoes_Id, ageDecoder); + registerDecoder(Tile::cactus_Id, ageDecoder); + registerDecoder(Tile::netherStalk_Id, ageDecoder); + registerDecoder(Tile::reeds_Id, ageDecoder); + registerDecoder(Tile::cocoa_Id, [](int composite)->std::wstring { return cocoaPropsToString(composite); }); + registerDecoder(Tile::brewingStand_Id, [](int composite)->std::wstring { return brewingStandPropsToString(composite); }); + registerDecoder(Tile::fire_Id, [](int composite)->std::wstring { return firePropsToString(composite); }); + registerDecoder(Tile::button_stone_Id, [](int composite)->std::wstring { return buttonPropsToString(composite); }); + registerDecoder(Tile::button_wood_Id, [](int composite)->std::wstring { return buttonPropsToString(composite); }); + registerDecoder(Tile::pumpkinStem_Id, [](int composite)->std::wstring { return stemPropsToString(composite); }); + registerDecoder(Tile::melonStem_Id, [](int composite)->std::wstring { return stemPropsToString(composite); }); + registerDecoder(Tile::vine_Id, [](int composite)->std::wstring { return vinePropsToString(composite); }); + registerDecoder(Tile::flowerPot_Id, [](int composite)->std::wstring { return flowerPotPropsToString(composite); }); + registerDecoder(Tile::sapling_Id, [](int composite)->std::wstring { return saplingPropsToString(composite); }); + registerDecoder(Tile::tallgrass_Id, [](int composite)->std::wstring { return tallGrassPropsToString(composite); }); + registerDecoder(Tile::tallgrass2_Id, [](int composite)->std::wstring { return tallGrass2PropsToString(composite); }); + registerDecoder(Tile::fenceGate_Id, [](int composite)->std::wstring { return fenceGatePropsToString(composite); }); + registerDecoder(Tile::spruceGate_Id, [](int composite)->std::wstring { return fenceGatePropsToString(composite); }); + registerDecoder(Tile::birchGate_Id, [](int composite)->std::wstring { return fenceGatePropsToString(composite); }); + registerDecoder(Tile::jungleGate_Id, [](int composite)->std::wstring { return fenceGatePropsToString(composite); }); + registerDecoder(Tile::darkGate_Id, [](int composite)->std::wstring { return fenceGatePropsToString(composite); }); + registerDecoder(Tile::acaciaGate_Id, [](int composite)->std::wstring { return fenceGatePropsToString(composite); }); + registerDecoder(Tile::fence_Id, [](int composite)->std::wstring { return fencePropsToString(composite); }); + registerDecoder(Tile::netherFence_Id, [](int composite)->std::wstring { return fencePropsToString(composite); }); + registerDecoder(Tile::spruceFence_Id, [](int composite)->std::wstring { return fencePropsToString(composite); }); + registerDecoder(Tile::birchFence_Id, [](int composite)->std::wstring { return fencePropsToString(composite); }); + registerDecoder(Tile::jungleFence_Id, [](int composite)->std::wstring { return fencePropsToString(composite); }); + registerDecoder(Tile::darkFence_Id, [](int composite)->std::wstring { return fencePropsToString(composite); }); + registerDecoder(Tile::acaciaFence_Id, [](int composite)->std::wstring { return fencePropsToString(composite); }); + registerDecoder(Tile::stoneSlab_Id, [](int composite)->std::wstring { return slabPropsToString(Tile::stoneSlab_Id, composite); }); + registerDecoder(Tile::stoneSlabHalf_Id, [](int composite)->std::wstring { return slabPropsToString(Tile::stoneSlabHalf_Id, composite); }); + registerDecoder(Tile::woodSlab_Id, [](int composite)->std::wstring { return slabPropsToString(Tile::woodSlab_Id, composite); }); + registerDecoder(Tile::woodSlabHalf_Id, [](int composite)->std::wstring { return slabPropsToString(Tile::woodSlabHalf_Id, composite); }); + registerDecoder(Tile::double_stone_slab2_Id, [](int composite)->std::wstring { return slabPropsToString(Tile::double_stone_slab2_Id, composite); }); + registerDecoder(Tile::stone_slab2_Id, [](int composite)->std::wstring { return slabPropsToString(Tile::stone_slab2_Id, composite); }); + registerDecoder(Tile::trapdoor_Id, [](int composite)->std::wstring { return trapDoorPropsToString(composite); }); + registerDecoder(Tile::iron_trapdoor_Id, [](int composite)->std::wstring { return trapDoorPropsToString(composite); }); + registerDecoder(Tile::tripWire_Id, [](int composite)->std::wstring { return tripWirePropsToString(composite); }); + registerDecoder(Tile::tripWireSource_Id, [](int composite)->std::wstring { return tripWireSourcePropsToString(composite); }); + registerDecoder(Tile::hayBlock_Id, [](int composite)->std::wstring { return hayBlockPropsToString(composite); }); + registerDecoder(Tile::treeTrunk_Id, [](int composite)->std::wstring { return logBlockPropsToString(Tile::treeTrunk_Id, composite); }); + registerDecoder(Tile::tree2Trunk_Id, [](int composite)->std::wstring { return logBlockPropsToString(Tile::tree2Trunk_Id, composite); }); + registerDecoder(Tile::lever_Id, [](int composite)->std::wstring { return leverPropsToString(composite); }); + registerDecoder(Tile::pistonBase_Id, [](int composite)->std::wstring { return pistonBasePropsToString(composite); }); + registerDecoder(Tile::pistonStickyBase_Id, [](int composite)->std::wstring { return pistonBasePropsToString(composite); }); + registerDecoder(Tile::pistonExtensionPiece_Id, [](int composite)->std::wstring { return pistonExtensionPropsToString(composite); }); + registerDecoder(Tile::endPortalFrameTile_Id, [](int composite)->std::wstring { return endPortalFramePropsToString(composite); }); + registerDecoder(Tile::diode_off_Id, [](int composite)->std::wstring { return repeaterPropsToString(composite, false); }); + registerDecoder(Tile::diode_on_Id, [](int composite)->std::wstring { return repeaterPropsToString(composite, true); }); + registerDecoder(Tile::hugeMushroom_brown_Id, [](int composite)->std::wstring { return hugeMushroomPropsToString(composite); }); + registerDecoder(Tile::hugeMushroom_red_Id, [](int composite)->std::wstring { return hugeMushroomPropsToString(composite); }); + registerDecoder(Tile::hopper_Id, [](int composite)->std::wstring { return hopperPropsToString(composite); }); + registerDecoder(Tile::jukebox_Id, [](int composite)->std::wstring { return jukeboxPropsToString(composite); }); + registerDecoder(Tile::daylightDetector_Id, [](int composite)->std::wstring { return daylightDetectorPropsToString(composite); }); + registerDecoder(Tile::invertedDaylightDetector_Id, [](int composite)->std::wstring { return daylightDetectorPropsToString(composite); }); + registerDecoder(Tile::snow_Id, [](int composite)->std::wstring { return snowPropsToString(composite); }); + registerDecoder(Tile::topSnow_Id, [](int composite)->std::wstring { return snowPropsToString(composite); }); + registerDecoder(Tile::cauldron_Id, [](int composite)->std::wstring { return cauldronPropsToString(composite); }); + registerDecoder(Tile::torch_Id, [](int composite)->std::wstring { return torchPropsToString(composite); }); + registerDecoder(Tile::furnace_Id, [](int composite)->std::wstring { return furnacePropsToString(composite); }); + registerDecoder(Tile::furnace_lit_Id, [](int composite)->std::wstring { return furnacePropsToString(composite); }); + registerDecoder(Tile::redStoneOre_Id, [](int composite)->std::wstring { return redstoneOrePropsToString(composite); }); + registerDecoder(Tile::redStoneOre_lit_Id, [](int composite)->std::wstring { return redstoneOrePropsToString(composite); }); + registerDecoder(Tile::redstoneTorch_off_Id, [](int composite)->std::wstring { return redstoneTorchPropsToString(composite); }); + registerDecoder(Tile::redstoneTorch_on_Id, [](int composite)->std::wstring { return redstoneTorchPropsToString(composite); }); + registerDecoder(Tile::redstoneLight_Id, [](int composite)->std::wstring { return redlightPropsToString(composite); }); + registerDecoder(Tile::redstoneLight_lit_Id, [](int composite)->std::wstring { return redlightPropsToString(composite); }); + return true; +registerDecoder(Tile::torch_Id, [](int composite)->std::wstring { return torchPropsToString(composite); }); +registerDecoder(Tile::furnace_Id, [](int composite)->std::wstring { return furnacePropsToString(composite); }); +registerDecoder(Tile::furnace_lit_Id, [](int composite)->std::wstring { return furnacePropsToString(composite); }); +registerDecoder(Tile::redStoneOre_Id, [](int composite)->std::wstring { return redstoneOrePropsToString(composite); }); +registerDecoder(Tile::redStoneOre_lit_Id, [](int composite)->std::wstring { return redstoneOrePropsToString(composite); }); +registerDecoder(Tile::redstoneTorch_off_Id, [](int composite)->std::wstring { return redstoneTorchPropsToString(composite); }); +registerDecoder(Tile::redstoneTorch_on_Id, [](int composite)->std::wstring { return redstoneTorchPropsToString(composite); }); +registerDecoder(Tile::redstoneLight_Id, [](int composite)->std::wstring { return redlightPropsToString(composite); }); +registerDecoder(Tile::redstoneLight_lit_Id, [](int composite)->std::wstring { return redlightPropsToString(composite); }); +} + +static bool s_plantDecoderRegistered = registerPlantDecoders(); diff --git a/Minecraft.World/BlockStateDecoder.h b/Minecraft.World/BlockStateDecoder.h new file mode 100644 index 00000000..815f89ef --- /dev/null +++ b/Minecraft.World/BlockStateDecoder.h @@ -0,0 +1,19 @@ +#pragma once +#include +#include "Tile.h" + +namespace BlockStateDecoder { + +// door stuff is here cause idk what i was doing when i intially started this +struct DoorProps { + int dir; + std::wstring dirName; + bool open; + bool upper; + bool hingeRight; +}; + +DoorProps decodeDoor(int composite); +std::wstring doorPropsToString(const DoorProps &p); + +} diff --git a/Minecraft.World/BlockStateDecoderRegistry.cpp b/Minecraft.World/BlockStateDecoderRegistry.cpp new file mode 100644 index 00000000..c9600fbf --- /dev/null +++ b/Minecraft.World/BlockStateDecoderRegistry.cpp @@ -0,0 +1,35 @@ +#include "BlockStateDecoderRegistry.h" +#include +#include + +namespace BlockStateDecoderRegistry { + +static std::unordered_map *g_map = nullptr; +static std::mutex g_mapMutex; + +static void ensureMap() +{ + if (!g_map) g_map = new std::unordered_map(); +} + +void registerDecoder(int tileId, DecoderFn fn) +{ + std::lock_guard l(g_mapMutex); + ensureMap(); + (*g_map)[tileId] = fn; +} + +std::wstring decode(int tileId, int composite) +{ + std::lock_guard l(g_mapMutex); + ensureMap(); + auto it = g_map->find(tileId); + if (it == g_map->end()) return L""; + try { + return it->second(composite); + } catch (...) { + return L""; + } +} + +} diff --git a/Minecraft.World/BlockStateDecoderRegistry.h b/Minecraft.World/BlockStateDecoderRegistry.h new file mode 100644 index 00000000..345ad939 --- /dev/null +++ b/Minecraft.World/BlockStateDecoderRegistry.h @@ -0,0 +1,12 @@ +#pragma once +#include +#include + +namespace BlockStateDecoderRegistry +{ + using DecoderFn = std::function; + + void registerDecoder(int tileId, DecoderFn fn); + + std::wstring decode(int tileId, int composite); +} diff --git a/Minecraft.World/BrewingStandTile.cpp b/Minecraft.World/BrewingStandTile.cpp index ec7242c8..24cd1fe2 100644 --- a/Minecraft.World/BrewingStandTile.cpp +++ b/Minecraft.World/BrewingStandTile.cpp @@ -13,6 +13,32 @@ BrewingStandTile::BrewingStandTile(int id) : BaseEntityTile(id, Material::metal, iconBase = nullptr; } +void BrewingStandTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int BrewingStandTile::defaultBlockState() +{ + return 0; +} + +int BrewingStandTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0x7) : 0; +} + +Tile::BlockState BrewingStandTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0x7); +} + +Tile::BlockState BrewingStandTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & 0x7); +} + BrewingStandTile::~BrewingStandTile() { delete random; diff --git a/Minecraft.World/BrewingStandTile.h b/Minecraft.World/BrewingStandTile.h index bb1fed99..f846d09e 100644 --- a/Minecraft.World/BrewingStandTile.h +++ b/Minecraft.World/BrewingStandTile.h @@ -14,6 +14,11 @@ private: public: BrewingStandTile(int id); ~BrewingStandTile(); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); virtual bool isSolidRender(bool isServerLevel = false); virtual int getRenderShape(); virtual shared_ptr newTileEntity(Level *level); diff --git a/Minecraft.World/ButtonTile.cpp b/Minecraft.World/ButtonTile.cpp index e95196a2..e6624a3c 100644 --- a/Minecraft.World/ButtonTile.cpp +++ b/Minecraft.World/ButtonTile.cpp @@ -13,6 +13,32 @@ ButtonTile::ButtonTile(int id, bool sensitive) : Tile(id, Material::decoration, this->sensitive = sensitive; } +void ButtonTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int ButtonTile::defaultBlockState() +{ + return 0; +} + +int ButtonTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0xF) : 0; +} + +Tile::BlockState ButtonTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0xF); +} + +Tile::BlockState ButtonTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & 0xF); +} + Icon *ButtonTile::getTexture(int face, int data) { if(id == Tile::button_wood_Id) return Tile::wood->getTexture(Facing::UP); diff --git a/Minecraft.World/ButtonTile.h b/Minecraft.World/ButtonTile.h index 96c49cdf..972c013a 100644 --- a/Minecraft.World/ButtonTile.h +++ b/Minecraft.World/ButtonTile.h @@ -18,6 +18,11 @@ protected: public: Icon *getTexture(int face, int data); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(int data); + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; virtual AABB *getAABB(Level *level, int x, int y, int z); virtual int getTickDelay(Level *level); virtual bool blocksLight(); diff --git a/Minecraft.World/CMakeLists.txt b/Minecraft.World/CMakeLists.txt index e397bf29..82169c29 100644 --- a/Minecraft.World/CMakeLists.txt +++ b/Minecraft.World/CMakeLists.txt @@ -11,6 +11,11 @@ set(MINECRAFT_WORLD_SOURCES ${SOURCES_COMMON} ) +list(APPEND MINECRAFT_WORLD_SOURCES + "${CMAKE_CURRENT_SOURCE_DIR}/BlockStateDecoder.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/BlockStateDecoderRegistry.cpp" +) + add_library(Minecraft.World STATIC ${MINECRAFT_WORLD_SOURCES}) target_include_directories(Minecraft.World diff --git a/Minecraft.World/CactusTile.cpp b/Minecraft.World/CactusTile.cpp index 731e722e..c63fc8c4 100644 --- a/Minecraft.World/CactusTile.cpp +++ b/Minecraft.World/CactusTile.cpp @@ -19,6 +19,32 @@ CactusTile::CactusTile(int id) : Tile(id, Material::cactus,isSolidRender()) iconBottom = nullptr; } +void CactusTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int CactusTile::defaultBlockState() +{ + return 0; +} + +int CactusTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0xF) : 0; +} + +Tile::BlockState CactusTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0xF); +} + +Tile::BlockState CactusTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & 0xF); +} + void CactusTile::tick(Level *level, int x, int y, int z, Random *random) { if (level->isEmptyTile(x, y + 1, z)) diff --git a/Minecraft.World/CactusTile.h b/Minecraft.World/CactusTile.h index 3c5e9b49..a5866a74 100644 --- a/Minecraft.World/CactusTile.h +++ b/Minecraft.World/CactusTile.h @@ -20,6 +20,11 @@ protected: CactusTile(int id); public: + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); virtual void tick(Level *level, int x, int y, int z, Random *random); virtual AABB *getAABB(Level *level, int x, int y, int z); virtual AABB *getTileAABB(Level *level, int x, int y, int z); diff --git a/Minecraft.World/CocoaTile.cpp b/Minecraft.World/CocoaTile.cpp index 2a2fbd21..ddb10067 100644 --- a/Minecraft.World/CocoaTile.cpp +++ b/Minecraft.World/CocoaTile.cpp @@ -17,6 +17,32 @@ CocoaTile::CocoaTile(int id) : DirectionalTile(id, Material::plant, isSolidRende setTicking(true); } +void CocoaTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int CocoaTile::defaultBlockState() +{ + return 0; +} + +int CocoaTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? state->value : 0; +} + +Tile::BlockState CocoaTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0xF); +} + +Tile::BlockState CocoaTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & 0xF); +} + Icon *CocoaTile::getTexture(int face, int data) { return icons[2]; diff --git a/Minecraft.World/CocoaTile.h b/Minecraft.World/CocoaTile.h index bcbb1d2f..78c1ca57 100644 --- a/Minecraft.World/CocoaTile.h +++ b/Minecraft.World/CocoaTile.h @@ -15,6 +15,11 @@ public: using Tile::setPlacedBy; CocoaTile(int id); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); virtual Icon *getTexture(int face, int data); virtual Icon *getTextureForAge(int age); diff --git a/Minecraft.World/CropTile.cpp b/Minecraft.World/CropTile.cpp index 9c2acf78..e02f4efe 100644 --- a/Minecraft.World/CropTile.cpp +++ b/Minecraft.World/CropTile.cpp @@ -21,6 +21,32 @@ CropTile::CropTile(int id) : Bush(id) sendTileData(); } +void CropTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int CropTile::defaultBlockState() +{ + return 0; +} + +int CropTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0x7) : 0; +} + +Tile::BlockState CropTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0x7); +} + +Tile::BlockState CropTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & 0x7); +} + // 4J Added override void CropTile::updateDefaultShape() { diff --git a/Minecraft.World/CropTile.h b/Minecraft.World/CropTile.h index 165fd4af..3fbde034 100644 --- a/Minecraft.World/CropTile.h +++ b/Minecraft.World/CropTile.h @@ -19,6 +19,11 @@ protected: public: // 4J Added override virtual void updateDefaultShape(); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); virtual void tick(Level *level, int x, int y, int z, Random *random); virtual void growCrops(Level *level, int x, int y, int z); private: diff --git a/Minecraft.World/DoorTile.cpp b/Minecraft.World/DoorTile.cpp index 300f4e39..8e351572 100644 --- a/Minecraft.World/DoorTile.cpp +++ b/Minecraft.World/DoorTile.cpp @@ -354,4 +354,86 @@ void DoorTile::playerWillDestroy(Level *level, int x, int y, int z, int data, sh } } } +} + +void DoorTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int DoorTile::defaultBlockState() +{ + return 0; // closed +} + +Tile::BlockState DoorTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + int composite = getCompositeData(level, x, y, z); + return Tile::BlockState(composite); +} + +int DoorTile::convertBlockStateToLegacyData(BlockState *state) +{ + if (!state) return 0; + int composite = state->value; + + if (composite & C_IS_UPPER_MASK) + { + int base = (composite & C_RIGHT_HINGE_MASK) ? 9 : 8; + if (composite & C_OPEN_MASK) base |= 2; + return base; + } + else + { + int base = composite & C_DIR_MASK; + if (composite & C_OPEN_MASK) base |= 4; + return base; + } +} + +Tile::BlockState DoorTile::getBlockState(int data) +{ + int composite = 0; + if ((data & UPPER_BIT) == 0) { + composite = data & C_LOWER_DATA_MASK; + } else { + composite = C_IS_UPPER_MASK; + if ((data & 1) != 0) composite |= C_RIGHT_HINGE_MASK; + } + return Tile::BlockState(composite); +} + +void DoorTile::fillVirtualBlockStateProperties(Tile::BlockState *state, LevelSource *level, const BlockPos &pos) +{ + if (!state) return; + int composite = getCompositeData(level, pos.getX(), pos.getY(), pos.getZ()); + state->value = composite; +} + +bool DoorTile::use(Level *level, const BlockPos &pos, Tile::BlockState *state, shared_ptr player, int clickedFace, float clickX, float clickY, float clickZ, bool soundOnly) +{ + if (soundOnly) + { + if (material != Material::metal) + level->levelEvent(player, LevelEvent::SOUND_OPEN_DOOR, pos.getX(), pos.getY(), pos.getZ(), 0); + return false; + } + + if (material == Material::metal) return true; + + int composite = state ? state->value : getCompositeData(level, pos.getX(), pos.getY(), pos.getZ()); + int lowerData = composite & C_LOWER_DATA_MASK; + lowerData ^= 4; + + if ((composite & C_IS_UPPER_MASK) == 0) { + level->setData(pos.getX(), pos.getY(), pos.getZ(), lowerData, Tile::UPDATE_CLIENTS); + level->setTilesDirty(pos.getX(), pos.getY(), pos.getZ(), pos.getX(), pos.getY(), pos.getZ()); + } else { + level->setData(pos.getX(), pos.getY() - 1, pos.getZ(), lowerData, Tile::UPDATE_CLIENTS); + level->setTilesDirty(pos.getX(), pos.getY() - 1, pos.getZ(), pos.getX(), pos.getY(), pos.getZ()); + } + + level->levelEvent(player, LevelEvent::SOUND_OPEN_DOOR, pos.getX(), pos.getY(), pos.getZ(), 0); + return true; } \ No newline at end of file diff --git a/Minecraft.World/DoorTile.h b/Minecraft.World/DoorTile.h index a2876d1c..a532e5cd 100644 --- a/Minecraft.World/DoorTile.h +++ b/Minecraft.World/DoorTile.h @@ -62,4 +62,15 @@ public: int getCompositeData(LevelSource *level, int x, int y, int z); virtual int cloneTileId(Level *level, int x, int y, int z); virtual void playerWillDestroy(Level *level, int x, int y, int z, int data, shared_ptr player); + + virtual void createBlockStateDefinition() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual int defaultBlockState() override; + + Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z); + Tile::BlockState getBlockState(int data); + + void fillVirtualBlockStateProperties(Tile::BlockState *state, LevelSource *level, const BlockPos &pos); + + virtual bool use(Level *level, const BlockPos &pos, Tile::BlockState *state, shared_ptr player, int clickedFace, float clickX, float clickY, float clickZ, bool soundOnly = false); }; diff --git a/Minecraft.World/FenceGateTile.cpp b/Minecraft.World/FenceGateTile.cpp index e01e76c6..784c5446 100644 --- a/Minecraft.World/FenceGateTile.cpp +++ b/Minecraft.World/FenceGateTile.cpp @@ -10,6 +10,32 @@ FenceGateTile::FenceGateTile(int id) : DirectionalTile(id, Material::wood, isSol { } +void FenceGateTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int FenceGateTile::defaultBlockState() +{ + return 0; +} + +int FenceGateTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0x7) : 0; +} + +Tile::BlockState FenceGateTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0x7); +} + +Tile::BlockState FenceGateTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z)); +} + Icon *FenceGateTile::getTexture(int face, int data) { return icon; diff --git a/Minecraft.World/FenceGateTile.h b/Minecraft.World/FenceGateTile.h index 585908d3..149f5da3 100644 --- a/Minecraft.World/FenceGateTile.h +++ b/Minecraft.World/FenceGateTile.h @@ -8,6 +8,11 @@ private: Icon* icon; public: FenceGateTile(int id); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); Icon *getTexture(int face, int data); virtual bool mayPlace(Level *level, int x, int y, int z); virtual AABB *getAABB(Level *level, int x, int y, int z); diff --git a/Minecraft.World/FenceTile.cpp b/Minecraft.World/FenceTile.cpp index 324d22ed..e5e3ca2c 100644 --- a/Minecraft.World/FenceTile.cpp +++ b/Minecraft.World/FenceTile.cpp @@ -10,6 +10,37 @@ FenceTile::FenceTile(int id, const wstring &texture, Material *material) : Tile( this->texture = texture; } +void FenceTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int FenceTile::defaultBlockState() +{ + return 0; +} + +int FenceTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0xF) : 0; +} + +Tile::BlockState FenceTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0xF); +} + +Tile::BlockState FenceTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + int state = 0; + if (connectsTo(level, x, y, z - 1)) state |= 0x1; + if (connectsTo(level, x, y, z + 1)) state |= 0x2; + if (connectsTo(level, x + 1, y, z)) state |= 0x4; + if (connectsTo(level, x - 1, y, z)) state |= 0x8; + return Tile::BlockState(state); +} + static const int fences[] = { Tile::fence_Id, Tile::netherFence_Id, Tile::spruceFence_Id, Tile::birchFence_Id, Tile::jungleFence_Id, Tile::acaciaFence_Id, Tile::darkFence_Id diff --git a/Minecraft.World/FenceTile.h b/Minecraft.World/FenceTile.h index ca22163a..84c0f7e4 100644 --- a/Minecraft.World/FenceTile.h +++ b/Minecraft.World/FenceTile.h @@ -9,6 +9,11 @@ private: public: FenceTile(int id, const wstring &texture, Material *material); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); virtual void addAABBs(Level *level, int x, int y, int z, AABB *box, AABBList *boxes, shared_ptr source); virtual void updateShape(LevelSource *level, int x, int y, int z, int forceData = -1, shared_ptr forceEntity = shared_ptr()); // 4J added forceData, forceEntity param virtual bool isSolidRender(bool isServerLevel = false); diff --git a/Minecraft.World/FireTile.cpp b/Minecraft.World/FireTile.cpp index f8e2fe4e..e7b81e4a 100644 --- a/Minecraft.World/FireTile.cpp +++ b/Minecraft.World/FireTile.cpp @@ -38,6 +38,41 @@ FireTile::~FireTile() delete [] burnOdds; } +void FireTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int FireTile::defaultBlockState() +{ + return 0; +} + +int FireTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & AGE_MASK) : 0; +} + +Tile::BlockState FireTile::getBlockState(int data) +{ + return Tile::BlockState(data & AGE_MASK); +} + +Tile::BlockState FireTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + int age = level->getData(x, y, z) & AGE_MASK; + int state = age; + + if (canBurn(level, x + 1, y, z)) state |= EAST_BIT; + if (canBurn(level, x - 1, y, z)) state |= WEST_BIT; + if (canBurn(level, x, y, z + 1)) state |= SOUTH_BIT; + if (canBurn(level, x, y, z - 1)) state |= NORTH_BIT; + if (canBurn(level, x, y + 1, z)) state |= UP_BIT; + + return Tile::BlockState(state); +} + void FireTile::init() { setFlammable(Tile::wood_Id, FLAME_HARD, BURN_MEDIUM); diff --git a/Minecraft.World/FireTile.h b/Minecraft.World/FireTile.h index 1d823752..97da6022 100644 --- a/Minecraft.World/FireTile.h +++ b/Minecraft.World/FireTile.h @@ -11,6 +11,12 @@ class FireTile : public Tile public: static const wstring TEXTURE_FIRST; static const wstring TEXTURE_SECOND; + static const int AGE_MASK = 0xF; + static const int EAST_BIT = 1 << 4; + static const int WEST_BIT = 1 << 5; + static const int SOUTH_BIT = 1 << 6; + static const int NORTH_BIT = 1 << 7; + static const int UP_BIT = 1 << 8; static const int FLAME_INSTANT = 60; static const int FLAME_EASY = 30; @@ -31,6 +37,11 @@ protected: FireTile(int id); virtual ~FireTile(); public: + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); void init(); private: void setFlammable(int id, int flame, int burn); diff --git a/Minecraft.World/FlowerPotTile.cpp b/Minecraft.World/FlowerPotTile.cpp index 80fdf2e4..d76df3a9 100644 --- a/Minecraft.World/FlowerPotTile.cpp +++ b/Minecraft.World/FlowerPotTile.cpp @@ -11,6 +11,32 @@ FlowerPotTile::FlowerPotTile(int id) : Tile(id, Material::decoration, isSolidRen sendTileData(); } +void FlowerPotTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int FlowerPotTile::defaultBlockState() +{ + return 0; +} + +int FlowerPotTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0xF) : 0; +} + +Tile::BlockState FlowerPotTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0xF); +} + +Tile::BlockState FlowerPotTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & 0xF); +} + void FlowerPotTile::updateDefaultShape() { float size = 6.0f / 16.0f; diff --git a/Minecraft.World/FlowerPotTile.h b/Minecraft.World/FlowerPotTile.h index 50dc18c4..a18c96f6 100644 --- a/Minecraft.World/FlowerPotTile.h +++ b/Minecraft.World/FlowerPotTile.h @@ -18,6 +18,11 @@ public: static const int TYPE_FERN = 11; FlowerPotTile(int id); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); void updateDefaultShape(); bool isSolidRender(bool isServerLevel = false); diff --git a/Minecraft.World/HalfSlabTile.cpp b/Minecraft.World/HalfSlabTile.cpp index e38b28c3..a4d5dcbc 100644 --- a/Minecraft.World/HalfSlabTile.cpp +++ b/Minecraft.World/HalfSlabTile.cpp @@ -12,6 +12,32 @@ HalfSlabTile::HalfSlabTile(int id, Material *material) Tile::lightBlock[id] = 0xFF; } +void HalfSlabTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int HalfSlabTile::defaultBlockState() +{ + return 0; +} + +int HalfSlabTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & (TYPE_MASK | TOP_SLOT_BIT)) : 0; +} + +Tile::BlockState HalfSlabTile::getBlockState(int data) +{ + return Tile::BlockState(data & (TYPE_MASK | TOP_SLOT_BIT)); +} + +Tile::BlockState HalfSlabTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & (TYPE_MASK | TOP_SLOT_BIT)); +} + void HalfSlabTile::DerivedInit() { diff --git a/Minecraft.World/HalfSlabTile.h b/Minecraft.World/HalfSlabTile.h index 7d65247b..45936e3f 100644 --- a/Minecraft.World/HalfSlabTile.h +++ b/Minecraft.World/HalfSlabTile.h @@ -21,6 +21,12 @@ public: virtual int isFullSize() = 0; + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); + virtual void updateShape( LevelSource *level, int x, int y, int z, int forceData = -1, diff --git a/Minecraft.World/HayBlockTile.cpp b/Minecraft.World/HayBlockTile.cpp index c782835c..2f3ef905 100644 --- a/Minecraft.World/HayBlockTile.cpp +++ b/Minecraft.World/HayBlockTile.cpp @@ -6,6 +6,31 @@ HayBlockTile::HayBlockTile(int id) : RotatedPillarTile(id, Material::grass) { } +void HayBlockTile::createBlockStateDefinition() +{ + RotatedPillarTile::createBlockStateDefinition(); +} + +int HayBlockTile::defaultBlockState() +{ + return 0; +} + +int HayBlockTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & MASK_FACING) : 0; +} + +Tile::BlockState HayBlockTile::getBlockState(int data) +{ + return Tile::BlockState(data & MASK_FACING); +} + +Tile::BlockState HayBlockTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & MASK_FACING); +} + int HayBlockTile::getRenderShape() { return SHAPE_TREE; diff --git a/Minecraft.World/HayBlockTile.h b/Minecraft.World/HayBlockTile.h index fca2e449..49a7d309 100644 --- a/Minecraft.World/HayBlockTile.h +++ b/Minecraft.World/HayBlockTile.h @@ -9,6 +9,11 @@ public: HayBlockTile(int id); int getRenderShape(); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); protected: Icon *getTypeTexture(int type); diff --git a/Minecraft.World/HopperTile.cpp b/Minecraft.World/HopperTile.cpp index 0371712a..6cb54f36 100644 --- a/Minecraft.World/HopperTile.cpp +++ b/Minecraft.World/HopperTile.cpp @@ -16,6 +16,32 @@ HopperTile::HopperTile(int id) : BaseEntityTile(id, Material::metal, isSolidRend setShape(0, 0, 0, 1, 1, 1); } +void HopperTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int HopperTile::defaultBlockState() +{ + return 0; +} + +int HopperTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0xF) : 0; +} + +Tile::BlockState HopperTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0xF); +} + +Tile::BlockState HopperTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return getBlockState(level->getData(x, y, z)); +} + void HopperTile::updateShape(LevelSource *level, int x, int y, int z, int forceData , shared_ptr forceEntity) { setShape(0, 0, 0, 1, 1, 1); diff --git a/Minecraft.World/HopperTile.h b/Minecraft.World/HopperTile.h index 12631587..2d0790ef 100644 --- a/Minecraft.World/HopperTile.h +++ b/Minecraft.World/HopperTile.h @@ -26,6 +26,12 @@ private: public: HopperTile(int id); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(int data); + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual void updateShape(LevelSource *level, int x, int y, int z, int forceData = -1, shared_ptr forceEntity = shared_ptr()); virtual void addAABBs(Level *level, int x, int y, int z, AABB *box, AABBList *boxes, shared_ptr source); virtual int getPlacedOnFaceDataValue(Level *level, int x, int y, int z, int face, float clickX, float clickY, float clickZ, int itemValue); diff --git a/Minecraft.World/HugeMushroomTile.cpp b/Minecraft.World/HugeMushroomTile.cpp index 8d3ef144..ce815db0 100644 --- a/Minecraft.World/HugeMushroomTile.cpp +++ b/Minecraft.World/HugeMushroomTile.cpp @@ -14,6 +14,32 @@ HugeMushroomTile::HugeMushroomTile(int id, Material *material, int type) : Tile( iconInside = nullptr; } +void HugeMushroomTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int HugeMushroomTile::defaultBlockState() +{ + return 0; +} + +int HugeMushroomTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0xF) : 0; +} + +Tile::BlockState HugeMushroomTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0xF); +} + +Tile::BlockState HugeMushroomTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return getBlockState(level->getData(x, y, z)); +} + Icon *HugeMushroomTile::getTexture(int face, int data) { // 123 diff --git a/Minecraft.World/HugeMushroomTile.h b/Minecraft.World/HugeMushroomTile.h index 0b45cf63..3b8c7731 100644 --- a/Minecraft.World/HugeMushroomTile.h +++ b/Minecraft.World/HugeMushroomTile.h @@ -21,6 +21,11 @@ private: Icon *iconInside; public: HugeMushroomTile(int id, Material *material, int type); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(int data); + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; Icon *getTexture(int face, int data); int getResourceCount(Random *random); int getResource(int data, Random *random, int playerBonusLevel); diff --git a/Minecraft.World/JukeboxTile.cpp b/Minecraft.World/JukeboxTile.cpp index 74e79e9e..f4098a06 100644 --- a/Minecraft.World/JukeboxTile.cpp +++ b/Minecraft.World/JukeboxTile.cpp @@ -66,6 +66,32 @@ JukeboxTile::JukeboxTile(int id) : BaseEntityTile(id, Material::wood) iconTop = nullptr; } +void JukeboxTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int JukeboxTile::defaultBlockState() +{ + return 0; +} + +int JukeboxTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0x1) : 0; +} + +Tile::BlockState JukeboxTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0x1); +} + +Tile::BlockState JukeboxTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & 0x1); +} + Icon *JukeboxTile::getTexture(int face, int data) { if (face == Facing::UP) diff --git a/Minecraft.World/JukeboxTile.h b/Minecraft.World/JukeboxTile.h index dd592872..0e41bf22 100644 --- a/Minecraft.World/JukeboxTile.h +++ b/Minecraft.World/JukeboxTile.h @@ -40,6 +40,11 @@ protected: JukeboxTile(int id); public: + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); virtual Icon *getTexture(int face, int data); virtual bool TestUse(Level *level, int x, int y, int z, shared_ptr player); virtual bool use(Level *level, int x, int y, int z, shared_ptr player, int clickedFace, float clickX, float clickY, float clickZ, bool soundOnly = false); // 4J added soundOnly param diff --git a/Minecraft.World/LeverTile.cpp b/Minecraft.World/LeverTile.cpp index 7a7cdfd5..3c4af525 100644 --- a/Minecraft.World/LeverTile.cpp +++ b/Minecraft.World/LeverTile.cpp @@ -8,6 +8,32 @@ LeverTile::LeverTile(int id) : Tile(id, Material::decoration,isSolidRender()) { } +void LeverTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int LeverTile::defaultBlockState() +{ + return 0; +} + +int LeverTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0xF) : 0; +} + +Tile::BlockState LeverTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0xF); +} + +Tile::BlockState LeverTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & 0xF); +} + AABB *LeverTile::getAABB(Level *level, int x, int y, int z) { return nullptr; diff --git a/Minecraft.World/LeverTile.h b/Minecraft.World/LeverTile.h index da719868..2f054e57 100644 --- a/Minecraft.World/LeverTile.h +++ b/Minecraft.World/LeverTile.h @@ -7,6 +7,11 @@ class LeverTile : public Tile protected: LeverTile(int id); public: + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(int data); + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; virtual AABB *getAABB(Level *level, int x, int y, int z); virtual bool blocksLight(); virtual bool isSolidRender(bool isServerLevel = false); diff --git a/Minecraft.World/NetherStalkTile.cpp b/Minecraft.World/NetherStalkTile.cpp index eadf9646..04e7ddf0 100644 --- a/Minecraft.World/NetherStalkTile.cpp +++ b/Minecraft.World/NetherStalkTile.cpp @@ -15,6 +15,32 @@ NetherStalkTile::NetherStalkTile(int id) : Bush(id) icons = NULL; } +void NetherStalkTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int NetherStalkTile::defaultBlockState() +{ + return 0; +} + +int NetherStalkTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0x3) : 0; +} + +Tile::BlockState NetherStalkTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0x3); +} + +Tile::BlockState NetherStalkTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & 0x3); +} + // 4J Added override void NetherStalkTile::updateDefaultShape() { diff --git a/Minecraft.World/NetherStalkTile.h b/Minecraft.World/NetherStalkTile.h index 39093274..81247aa3 100644 --- a/Minecraft.World/NetherStalkTile.h +++ b/Minecraft.World/NetherStalkTile.h @@ -16,6 +16,11 @@ private: public: NetherStalkTile(int id); virtual void updateDefaultShape(); // 4J Added override + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); virtual bool mayPlaceOn(int tile); // Brought forward to fix #60073 - TU7: Content: Gameplay: Nether Warts cannot be placed next to each other in the Nether diff --git a/Minecraft.World/NetherWartTile.cpp b/Minecraft.World/NetherWartTile.cpp index 3c855040..ba312d26 100644 --- a/Minecraft.World/NetherWartTile.cpp +++ b/Minecraft.World/NetherWartTile.cpp @@ -15,6 +15,32 @@ NetherWartTile::NetherWartTile(int id) : Bush(id) updateDefaultShape(); } +void NetherWartTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int NetherWartTile::defaultBlockState() +{ + return 0; +} + +int NetherWartTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0x3) : 0; +} + +Tile::BlockState NetherWartTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0x3); +} + +Tile::BlockState NetherWartTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & 0x3); +} + // 4J Added override void NetherWartTile::updateDefaultShape() { diff --git a/Minecraft.World/NetherWartTile.h b/Minecraft.World/NetherWartTile.h index 3e5088b2..d43f272b 100644 --- a/Minecraft.World/NetherWartTile.h +++ b/Minecraft.World/NetherWartTile.h @@ -14,6 +14,11 @@ private: public: NetherWartTile(int id); virtual void updateDefaultShape(); // 4J Added override + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); virtual bool mayPlaceOn(int tile); // Brought forward to fix #60073 - TU7: Content: Gameplay: Nether Warts cannot be placed next to each other in the Nether diff --git a/Minecraft.World/PistonBaseTile.cpp b/Minecraft.World/PistonBaseTile.cpp index b5196471..e0a0a30b 100644 --- a/Minecraft.World/PistonBaseTile.cpp +++ b/Minecraft.World/PistonBaseTile.cpp @@ -53,6 +53,32 @@ PistonBaseTile::PistonBaseTile(int id, bool isSticky) : Tile(id, Material::pisto iconPlatform = nullptr; } +void PistonBaseTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int PistonBaseTile::defaultBlockState() +{ + return 0; +} + +int PistonBaseTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0xF) : 0; +} + +Tile::BlockState PistonBaseTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0xF); +} + +Tile::BlockState PistonBaseTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & 0xF); +} + Icon *PistonBaseTile::getPlatformTexture() { return iconPlatform; diff --git a/Minecraft.World/PistonBaseTile.h b/Minecraft.World/PistonBaseTile.h index 59c2e833..cd80b785 100644 --- a/Minecraft.World/PistonBaseTile.h +++ b/Minecraft.World/PistonBaseTile.h @@ -32,6 +32,11 @@ private: public: PistonBaseTile(int id, bool isSticky); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(int data); + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; Icon *getPlatformTexture(); virtual void updateShape(float x0, float y0, float z0, float x1, float y1, float z1); diff --git a/Minecraft.World/PistonExtensionTile.cpp b/Minecraft.World/PistonExtensionTile.cpp index bf5e6e60..dfd46cd8 100644 --- a/Minecraft.World/PistonExtensionTile.cpp +++ b/Minecraft.World/PistonExtensionTile.cpp @@ -13,6 +13,32 @@ PistonExtensionTile::PistonExtensionTile(int id) : Tile(id, Material::piston,isS setDestroyTime(0.5f); } +void PistonExtensionTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int PistonExtensionTile::defaultBlockState() +{ + return 0; +} + +int PistonExtensionTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0xF) : 0; +} + +Tile::BlockState PistonExtensionTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0xF); +} + +Tile::BlockState PistonExtensionTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & 0xF); +} + void PistonExtensionTile::setOverrideTopTexture(Icon *overrideTopTexture) { this->overrideTopTexture = overrideTopTexture; diff --git a/Minecraft.World/PistonExtensionTile.h b/Minecraft.World/PistonExtensionTile.h index bd00b8e2..7725707f 100644 --- a/Minecraft.World/PistonExtensionTile.h +++ b/Minecraft.World/PistonExtensionTile.h @@ -12,6 +12,11 @@ private: public: PistonExtensionTile(int id); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(int data); + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; virtual void setOverrideTopTexture(Icon *overrideTopTexture); virtual void clearOverrideTopTexture(); virtual void playerWillDestroy(Level *level, int x, int y, int z, int data, shared_ptr player); diff --git a/Minecraft.World/ReedTile.cpp b/Minecraft.World/ReedTile.cpp index b67c4874..db56c9bc 100644 --- a/Minecraft.World/ReedTile.cpp +++ b/Minecraft.World/ReedTile.cpp @@ -16,6 +16,32 @@ ReedTile::ReedTile(int id) : Tile( id, Material::plant,isSolidRender() ) this->setTicking(true); } +void ReedTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int ReedTile::defaultBlockState() +{ + return 0; +} + +int ReedTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0xF) : 0; +} + +Tile::BlockState ReedTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0xF); +} + +Tile::BlockState ReedTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & 0xF); +} + // 4J Added override void ReedTile::updateDefaultShape() { diff --git a/Minecraft.World/ReedTile.h b/Minecraft.World/ReedTile.h index bc2a0366..16bc4494 100644 --- a/Minecraft.World/ReedTile.h +++ b/Minecraft.World/ReedTile.h @@ -14,6 +14,11 @@ protected: public: virtual void updateDefaultShape(); // 4J Added override + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); void tick(Level *level, int x, int y, int z, Random* random); public: diff --git a/Minecraft.World/RepeaterTile.cpp b/Minecraft.World/RepeaterTile.cpp index 23a9e12f..f15fc0d4 100644 --- a/Minecraft.World/RepeaterTile.cpp +++ b/Minecraft.World/RepeaterTile.cpp @@ -12,6 +12,32 @@ RepeaterTile::RepeaterTile(int id, bool on) : DiodeTile(id, on) { } +void RepeaterTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int RepeaterTile::defaultBlockState() +{ + return 0; +} + +int RepeaterTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0xF) : 0; +} + +Tile::BlockState RepeaterTile::getBlockState(int data) +{ + return Tile::BlockState((data & 0xF) | ((on ? 1 : 0) << 4)); +} + +Tile::BlockState RepeaterTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return getBlockState(level->getData(x, y, z)); +} + bool RepeaterTile::use(Level *level, int x, int y, int z, shared_ptr player, int clickedFace, float clickX, float clickY, float clickZ, bool soundOnly) { if (soundOnly) return false; diff --git a/Minecraft.World/RepeaterTile.h b/Minecraft.World/RepeaterTile.h index 048e4de0..0c7091f1 100644 --- a/Minecraft.World/RepeaterTile.h +++ b/Minecraft.World/RepeaterTile.h @@ -16,6 +16,12 @@ private: public: RepeaterTile(int id, bool on); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(int data); + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual bool use(Level *level, int x, int y, int z, shared_ptr player, int clickedFace, float clickX, float clickY, float clickZ, bool soundOnly = false); protected: diff --git a/Minecraft.World/RotatedPillarTile.cpp b/Minecraft.World/RotatedPillarTile.cpp index 6475cd72..fbfc00d2 100644 --- a/Minecraft.World/RotatedPillarTile.cpp +++ b/Minecraft.World/RotatedPillarTile.cpp @@ -6,6 +6,32 @@ RotatedPillarTile::RotatedPillarTile(int id, Material *material) : Tile(id, mate { } +void RotatedPillarTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int RotatedPillarTile::defaultBlockState() +{ + return 0; +} + +int RotatedPillarTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & MASK_FACING) : 0; +} + +Tile::BlockState RotatedPillarTile::getBlockState(int data) +{ + return Tile::BlockState(data & MASK_FACING); +} + +Tile::BlockState RotatedPillarTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & MASK_FACING); +} + int RotatedPillarTile::getRenderShape() { return Tile::SHAPE_TREE; diff --git a/Minecraft.World/RotatedPillarTile.h b/Minecraft.World/RotatedPillarTile.h index 76e52997..a01f3560 100644 --- a/Minecraft.World/RotatedPillarTile.h +++ b/Minecraft.World/RotatedPillarTile.h @@ -17,6 +17,11 @@ protected: RotatedPillarTile(int id, Material *material); public: + virtual void createBlockStateDefinition(); + virtual int defaultBlockState(); + virtual int convertBlockStateToLegacyData(BlockState *state); + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z); + virtual Tile::BlockState getBlockState(int data); virtual int getRenderShape(); virtual int getPlacedOnFaceDataValue(Level *level, int x, int y, int z, int face, float clickX, float clickY, float clickZ, int itemValue); virtual Icon *getTexture(int face, int data); diff --git a/Minecraft.World/Sapling.cpp b/Minecraft.World/Sapling.cpp index 93b15039..5c76d3fa 100644 --- a/Minecraft.World/Sapling.cpp +++ b/Minecraft.World/Sapling.cpp @@ -38,6 +38,32 @@ Sapling::Sapling(int id) : Bush(id) icons = nullptr; } +void Sapling::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int Sapling::defaultBlockState() +{ + return 0; +} + +int Sapling::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & (TYPE_MASK | AGE_BIT)) : 0; +} + +Tile::BlockState Sapling::getBlockState(int data) +{ + return Tile::BlockState(data & (TYPE_MASK | AGE_BIT)); +} + +Tile::BlockState Sapling::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & (TYPE_MASK | AGE_BIT)); +} + void Sapling::updateDefaultShape() { float ss = 0.4f; diff --git a/Minecraft.World/Sapling.h b/Minecraft.World/Sapling.h index 7d1e287b..cfeac0f3 100644 --- a/Minecraft.World/Sapling.h +++ b/Minecraft.World/Sapling.h @@ -37,6 +37,11 @@ protected: Sapling(int id); public: + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); virtual void updateDefaultShape(); // 4J Added override virtual void tick(Level *level, int x, int y, int z, Random *random); diff --git a/Minecraft.World/StairTile.cpp b/Minecraft.World/StairTile.cpp index 00607736..f3a622f6 100644 --- a/Minecraft.World/StairTile.cpp +++ b/Minecraft.World/StairTile.cpp @@ -529,3 +529,189 @@ void StairTile::registerIcons(IconRegister *iconRegister) { // None } + +void StairTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int StairTile::defaultBlockState() +{ + return 0; // default state +} + +Tile::BlockState StairTile::getBlockState(int data) +{ + int composite = data & 0x3; + if ((data & UPSIDEDOWN_BIT) != 0) composite |= UPSIDEDOWN_BIT; + return Tile::BlockState(composite); +} + +Tile::BlockState StairTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + int data = level->getData(x, y, z); + int dir = data & 0x3; + bool upsideDown = (data & UPSIDEDOWN_BIT) != 0; + + int shape = 0; + + bool checkInnerPiece = true; + if (dir == DIR_EAST) + { + int backTile = level->getTile(x + 1, y, z); + int backData = level->getData(x + 1, y, z); + if (isStairs(backTile) && ((backData & UPSIDEDOWN_BIT) == (data & UPSIDEDOWN_BIT))) + { + int backDir = backData & 0x3; + if (backDir == DIR_NORTH && !isLockAttached(level, x, y, z + 1, data)) + { + checkInnerPiece = false; + } + else if (backDir == DIR_SOUTH && !isLockAttached(level, x, y, z - 1, data)) + { + checkInnerPiece = false; + } + } + } + else if (dir == DIR_WEST) + { + int backTile = level->getTile(x - 1, y, z); + int backData = level->getData(x - 1, y, z); + if (isStairs(backTile) && ((backData & UPSIDEDOWN_BIT) == (data & UPSIDEDOWN_BIT))) + { + int backDir = backData & 0x3; + if (backDir == DIR_NORTH && !isLockAttached(level, x, y, z + 1, data)) + { + checkInnerPiece = false; + } + else if (backDir == DIR_SOUTH && !isLockAttached(level, x, y, z - 1, data)) + { + checkInnerPiece = false; + } + } + } + else if (dir == DIR_SOUTH) + { + int backTile = level->getTile(x, y, z + 1); + int backData = level->getData(x, y, z + 1); + if (isStairs(backTile) && ((backData & UPSIDEDOWN_BIT) == (data & UPSIDEDOWN_BIT))) + { + int backDir = backData & 0x3; + if (backDir == DIR_WEST && !isLockAttached(level, x + 1, y, z, data)) + { + checkInnerPiece = false; + } + else if (backDir == DIR_EAST && !isLockAttached(level, x - 1, y, z, data)) + { + checkInnerPiece = false; + } + } + } + else if (dir == DIR_NORTH) + { + int backTile = level->getTile(x, y, z - 1); + int backData = level->getData(x, y, z - 1); + if (isStairs(backTile) && ((backData & UPSIDEDOWN_BIT) == (data & UPSIDEDOWN_BIT))) + { + int backDir = backData & 0x3; + if (backDir == DIR_WEST && !isLockAttached(level, x + 1, y, z, data)) + { + checkInnerPiece = false; + } + else if (backDir == DIR_EAST && !isLockAttached(level, x - 1, y, z, data)) + { + checkInnerPiece = false; + } + } + } + + if (!checkInnerPiece) + { + shape = 2; + } + else + { + bool hasInnerPiece = false; + if (dir == DIR_EAST) + { + int frontTile = level->getTile(x - 1, y, z); + int frontData = level->getData(x - 1, y, z); + if (isStairs(frontTile) && ((frontData & UPSIDEDOWN_BIT) == (data & UPSIDEDOWN_BIT))) + { + int frontDir = frontData & 0x3; + if ((frontDir == DIR_NORTH && !isLockAttached(level, x, y, z - 1, data)) || + (frontDir == DIR_SOUTH && !isLockAttached(level, x, y, z + 1, data))) + { + hasInnerPiece = true; + } + } + } + else if (dir == DIR_WEST) + { + int frontTile = level->getTile(x + 1, y, z); + int frontData = level->getData(x + 1, y, z); + if (isStairs(frontTile) && ((frontData & UPSIDEDOWN_BIT) == (data & UPSIDEDOWN_BIT))) + { + int frontDir = frontData & 0x3; + if ((frontDir == DIR_NORTH && !isLockAttached(level, x, y, z - 1, data)) || + (frontDir == DIR_SOUTH && !isLockAttached(level, x, y, z + 1, data))) + { + hasInnerPiece = true; + } + } + } + else if (dir == DIR_SOUTH) + { + int frontTile = level->getTile(x, y, z - 1); + int frontData = level->getData(x, y, z - 1); + if (isStairs(frontTile) && ((frontData & UPSIDEDOWN_BIT) == (data & UPSIDEDOWN_BIT))) + { + int frontDir = frontData & 0x3; + if ((frontDir == DIR_WEST && !isLockAttached(level, x - 1, y, z, data)) || + (frontDir == DIR_EAST && !isLockAttached(level, x + 1, y, z, data))) + { + hasInnerPiece = true; + } + } + } + else if (dir == DIR_NORTH) + { + int frontTile = level->getTile(x, y, z + 1); + int frontData = level->getData(x, y, z + 1); + if (isStairs(frontTile) && ((frontData & UPSIDEDOWN_BIT) == (data & UPSIDEDOWN_BIT))) + { + int frontDir = frontData & 0x3; + if ((frontDir == DIR_WEST && !isLockAttached(level, x - 1, y, z, data)) || + (frontDir == DIR_EAST && !isLockAttached(level, x + 1, y, z, data))) + { + hasInnerPiece = true; + } + } + } + + if (hasInnerPiece) + { + shape = 1; + } + } + + int composite = (dir & 0x3) | (upsideDown ? UPSIDEDOWN_BIT : 0) | ((shape & 0x7) << 3); + return Tile::BlockState(composite); +} + +int StairTile::convertBlockStateToLegacyData(BlockState *state) +{ + if (!state) return 0; + int composite = state->value; + int data = composite & 0x3; + if (composite & UPSIDEDOWN_BIT) data |= UPSIDEDOWN_BIT; + return data; +} + +void StairTile::fillVirtualBlockStateProperties(Tile::BlockState *state, LevelSource *level, const BlockPos &pos) +{ + if (!state) return; + Tile::BlockState s = getBlockState(level, pos.getX(), pos.getY(), pos.getZ()); + state->value = s.value; +} diff --git a/Minecraft.World/StairTile.h b/Minecraft.World/StairTile.h index ff5d57ff..6e502887 100644 --- a/Minecraft.World/StairTile.h +++ b/Minecraft.World/StairTile.h @@ -76,4 +76,13 @@ public: virtual int getPlacedOnFaceDataValue(Level *level, int x, int y, int z, int face, float clickX, float clickY, float clickZ, int itemValue); virtual HitResult *clip(Level *level, int xt, int yt, int zt, Vec3 *a, Vec3 *b); virtual void registerIcons(IconRegister *iconRegister); + + virtual void createBlockStateDefinition() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual int defaultBlockState() override; + + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + Tile::BlockState getBlockState(int data); + + void fillVirtualBlockStateProperties(Tile::BlockState *state, LevelSource *level, const BlockPos &pos); }; diff --git a/Minecraft.World/StemTile.cpp b/Minecraft.World/StemTile.cpp index 66980f58..7997b903 100644 --- a/Minecraft.World/StemTile.cpp +++ b/Minecraft.World/StemTile.cpp @@ -24,6 +24,35 @@ StemTile::StemTile(int id, Tile *fruit) : Bush(id) iconAngled = nullptr; } +void StemTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int StemTile::defaultBlockState() +{ + return 0; +} + +int StemTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0x7) : 0; +} + +Tile::BlockState StemTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0x7); +} + +Tile::BlockState StemTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + int age = level->getData(x, y, z) & 0x7; + int connectDir = getConnectDir(level, x, y, z); + int facingCode = connectDir >= 0 ? connectDir + 1 : 0; + return Tile::BlockState(age | ((facingCode & 0x7) << 3)); +} + bool StemTile::mayPlaceOn(int tile) { return tile == Tile::farmland_Id; diff --git a/Minecraft.World/StemTile.h b/Minecraft.World/StemTile.h index 4685e0a5..c8caf938 100644 --- a/Minecraft.World/StemTile.h +++ b/Minecraft.World/StemTile.h @@ -15,6 +15,11 @@ private: public: StemTile(int id, Tile *fruit); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); virtual bool mayPlaceOn(int tile); public: diff --git a/Minecraft.World/TallGrass.cpp b/Minecraft.World/TallGrass.cpp index 943d9e1d..1b99e587 100644 --- a/Minecraft.World/TallGrass.cpp +++ b/Minecraft.World/TallGrass.cpp @@ -19,6 +19,32 @@ TallGrass::TallGrass(int id) : Bush(id, Material::replaceable_plant) this->updateDefaultShape(); } +void TallGrass::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int TallGrass::defaultBlockState() +{ + return 0; +} + +int TallGrass::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0x3) : 0; +} + +Tile::BlockState TallGrass::getBlockState(int data) +{ + return Tile::BlockState(data & 0x3); +} + +Tile::BlockState TallGrass::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & 0x3); +} + // 4J Added override void TallGrass::updateDefaultShape() { diff --git a/Minecraft.World/TallGrass.h b/Minecraft.World/TallGrass.h index 9b4c5515..53583e9e 100644 --- a/Minecraft.World/TallGrass.h +++ b/Minecraft.World/TallGrass.h @@ -25,6 +25,11 @@ protected: public: virtual void updateDefaultShape(); // 4J Added override + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); virtual Icon *getTexture(int face, int data); virtual int getColor(int auxData); diff --git a/Minecraft.World/TallGrass2.cpp b/Minecraft.World/TallGrass2.cpp index 93c0538c..4b9abd77 100644 --- a/Minecraft.World/TallGrass2.cpp +++ b/Minecraft.World/TallGrass2.cpp @@ -53,6 +53,32 @@ TallGrass2::TallGrass2(int id) : Bush(id, Material::replaceable_plant) this->updateDefaultShape(); } +void TallGrass2::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int TallGrass2::defaultBlockState() +{ + return 0; +} + +int TallGrass2::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0xF) : 0; +} + +Tile::BlockState TallGrass2::getBlockState(int data) +{ + return Tile::BlockState(data & 0xF); +} + +Tile::BlockState TallGrass2::getBlockState(LevelSource* level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & 0xF); +} + void TallGrass2::updateDefaultShape() { diff --git a/Minecraft.World/TallGrass2.h b/Minecraft.World/TallGrass2.h index 1be2f485..5da5b2f4 100644 --- a/Minecraft.World/TallGrass2.h +++ b/Minecraft.World/TallGrass2.h @@ -24,6 +24,11 @@ protected: public: virtual void updateDefaultShape() override; + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource* level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); virtual Icon* getTexture(int face, int data) override; virtual Icon* getTexture(LevelSource* level, int x, int y, int z, int face) override; virtual void registerIcons(IconRegister* iconRegister) override; diff --git a/Minecraft.World/TheEndPortalFrameTile.cpp b/Minecraft.World/TheEndPortalFrameTile.cpp index 80e78f49..96aafca2 100644 --- a/Minecraft.World/TheEndPortalFrameTile.cpp +++ b/Minecraft.World/TheEndPortalFrameTile.cpp @@ -13,6 +13,32 @@ TheEndPortalFrameTile::TheEndPortalFrameTile(int id) : Tile(id, Material::glass, iconEye = nullptr; } +void TheEndPortalFrameTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int TheEndPortalFrameTile::defaultBlockState() +{ + return 0; +} + +int TheEndPortalFrameTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0x7) : 0; +} + +Tile::BlockState TheEndPortalFrameTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0x7); +} + +Tile::BlockState TheEndPortalFrameTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & 0x7); +} + Icon *TheEndPortalFrameTile::getTexture(int face, int data) { if (face == Facing::UP) diff --git a/Minecraft.World/TheEndPortalFrameTile.h b/Minecraft.World/TheEndPortalFrameTile.h index d3119d00..b092d459 100644 --- a/Minecraft.World/TheEndPortalFrameTile.h +++ b/Minecraft.World/TheEndPortalFrameTile.h @@ -13,6 +13,11 @@ private: public: TheEndPortalFrameTile(int id); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(int data); + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; virtual Icon *getTexture(int face, int data); void registerIcons(IconRegister *iconRegister); Icon *getEye(); diff --git a/Minecraft.World/Tile.cpp b/Minecraft.World/Tile.cpp index b25c6fc5..925217f5 100644 --- a/Minecraft.World/Tile.cpp +++ b/Minecraft.World/Tile.cpp @@ -287,6 +287,45 @@ void Tile::ReleaseThreadStorage() ThreadStorage *tls = static_cast(TlsGetValue(Tile::tlsIdxShape)); delete tls; } + +Tile::BlockStateDefinition::BlockStateDefinition(Tile *ownerTile) +{ + owner = ownerTile; +} + +void Tile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int Tile::defaultBlockState() +{ + return m_defaultBlockState; +} + +Tile::BlockStateDefinition *Tile::getBlockStateDefinition() +{ + return m_blockStateDefinition; +} + +int Tile::convertBlockStateToLegacyData(BlockState *state) +{ + (void)state; + return 0; +} + +int Tile::getBlockState() +{ + return m_defaultBlockState; +} + +Tile::BlockState Tile::getBlockState(LevelSource *level, int x, int y, int z) +{ + (void)level; (void)x; (void)y; (void)z; + return BlockState(defaultBlockState()); +} + class TallGrass2TileItem : public ColoredTileItem { public: @@ -659,6 +698,9 @@ void Tile::_init(int id, Material *material, bool isSolidRender) _isTicking = false; _isEntityTile = false; + m_blockStateDefinition = nullptr; + m_defaultBlockState = 0; + /* 4J - TODO if (Tile.tiles[id] != null) { diff --git a/Minecraft.World/Tile.h b/Minecraft.World/Tile.h index 8afc8d21..2c92df70 100644 --- a/Minecraft.World/Tile.h +++ b/Minecraft.World/Tile.h @@ -65,6 +65,30 @@ protected: }; static DWORD tlsIdxShape; public: + class BlockState { + public: + int value; + BlockState(int v = 0) : value(v) {} + }; + + class BlockStateDefinition { + public: + Tile *owner; + BlockStateDefinition(Tile *ownerTile); + }; + + // create blockstate definition + virtual void createBlockStateDefinition(); + // return default tile blockstate + virtual int defaultBlockState(); + // return blockstate definition + virtual BlockStateDefinition *getBlockStateDefinition(); + // convert blockstate to legacy bitmask + virtual int convertBlockStateToLegacyData(BlockState *state); + // defaultblockstate part 2 + virtual int getBlockState(); + // return blockstate for tile at world position + virtual BlockState getBlockState(LevelSource *level, int x, int y, int z); // Each new thread that needs to use Vec3 pools will need to call one of the following 2 functions, to either create its own // local storage, or share the default storage already allocated by the main thread static void CreateNewThreadStorage(); @@ -654,6 +678,9 @@ protected: int m_iMaterial; int m_iBaseItemType; + BlockStateDefinition *m_blockStateDefinition; + int m_defaultBlockState; + // 4J Stu - Removed this in favour of a TLS version //double xx0, yy0, zz0, xx1, yy1, zz1; diff --git a/Minecraft.World/TrapDoorTile.cpp b/Minecraft.World/TrapDoorTile.cpp index 6ea64172..518ba59c 100644 --- a/Minecraft.World/TrapDoorTile.cpp +++ b/Minecraft.World/TrapDoorTile.cpp @@ -13,6 +13,32 @@ TrapDoorTile::TrapDoorTile(int id, Material *material) : Tile(id, material,isSol setShape(0.5f - r, 0, 0.5f - r, 0.5f + r, h, 0.5f + r); } +void TrapDoorTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int TrapDoorTile::defaultBlockState() +{ + return 0; +} + +int TrapDoorTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0xF) : 0; +} + +Tile::BlockState TrapDoorTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0xF); +} + +Tile::BlockState TrapDoorTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & 0xF); +} + bool TrapDoorTile::blocksLight() { return false; diff --git a/Minecraft.World/TrapDoorTile.h b/Minecraft.World/TrapDoorTile.h index 19cec150..9629c50a 100644 --- a/Minecraft.World/TrapDoorTile.h +++ b/Minecraft.World/TrapDoorTile.h @@ -25,6 +25,11 @@ protected: public: bool blocksLight(); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); public: bool isSolidRender(bool isServerLevel = false); diff --git a/Minecraft.World/TreeTile.cpp b/Minecraft.World/TreeTile.cpp index 6cf8da8b..93a7efcb 100644 --- a/Minecraft.World/TreeTile.cpp +++ b/Minecraft.World/TreeTile.cpp @@ -21,6 +21,32 @@ TreeTile::TreeTile(int id) : RotatedPillarTile(id, Material::wood) { } +void TreeTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int TreeTile::defaultBlockState() +{ + return 0; +} + +int TreeTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & (MASK_TYPE | MASK_FACING)) : 0; +} + +Tile::BlockState TreeTile::getBlockState(int data) +{ + return Tile::BlockState(data & (MASK_TYPE | MASK_FACING)); +} + +Tile::BlockState TreeTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & (MASK_TYPE | MASK_FACING)); +} + int TreeTile::getResourceCount(Random *random) { return 1; diff --git a/Minecraft.World/TreeTile.h b/Minecraft.World/TreeTile.h index f227e80a..fdcfcc13 100644 --- a/Minecraft.World/TreeTile.h +++ b/Minecraft.World/TreeTile.h @@ -42,6 +42,11 @@ protected: public: virtual int getResourceCount(Random *random); virtual int getResource(int data, Random *random, int playerBonusLevel); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); virtual void onRemove(Level *level, int x, int y, int z, int id, int data); virtual unsigned int getDescriptionId(int iData = -1); diff --git a/Minecraft.World/TreeTile2.cpp b/Minecraft.World/TreeTile2.cpp index 405c2add..ff7bedc8 100644 --- a/Minecraft.World/TreeTile2.cpp +++ b/Minecraft.World/TreeTile2.cpp @@ -17,6 +17,32 @@ TreeTile2::TreeTile2(int id) : RotatedPillarTile(id, Material::wood) { } +void TreeTile2::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int TreeTile2::defaultBlockState() +{ + return 0; +} + +int TreeTile2::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & (MASK_TYPE | MASK_FACING)) : 0; +} + +Tile::BlockState TreeTile2::getBlockState(int data) +{ + return Tile::BlockState(data & (MASK_TYPE | MASK_FACING)); +} + +Tile::BlockState TreeTile2::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & (MASK_TYPE | MASK_FACING)); +} + int TreeTile2::getResourceCount(Random* random) { return 1; diff --git a/Minecraft.World/TreeTile2.h b/Minecraft.World/TreeTile2.h index 412341ac..168620d4 100644 --- a/Minecraft.World/TreeTile2.h +++ b/Minecraft.World/TreeTile2.h @@ -38,6 +38,11 @@ protected: public: virtual int getResourceCount(Random* random); virtual int getResource(int data, Random* random, int playerBonusLevel); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); virtual void onRemove(Level* level, int x, int y, int z, int id, int data); protected: diff --git a/Minecraft.World/TripWireSourceTile.cpp b/Minecraft.World/TripWireSourceTile.cpp index fcd7564d..d85de44c 100644 --- a/Minecraft.World/TripWireSourceTile.cpp +++ b/Minecraft.World/TripWireSourceTile.cpp @@ -10,6 +10,32 @@ TripWireSourceTile::TripWireSourceTile(int id) : Tile(id, Material::decoration, this->setTicking(true); } +void TripWireSourceTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int TripWireSourceTile::defaultBlockState() +{ + return 0; +} + +int TripWireSourceTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0xF) : 0; +} + +Tile::BlockState TripWireSourceTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0xF); +} + +Tile::BlockState TripWireSourceTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & 0xF); +} + AABB *TripWireSourceTile::getAABB(Level *level, int x, int y, int z) { return nullptr; diff --git a/Minecraft.World/TripWireSourceTile.h b/Minecraft.World/TripWireSourceTile.h index 83adb9ab..fcb26e14 100644 --- a/Minecraft.World/TripWireSourceTile.h +++ b/Minecraft.World/TripWireSourceTile.h @@ -14,6 +14,11 @@ public: static const int WIRE_DIST_MAX = 2 + 40; // 2 hooks + x string TripWireSourceTile(int id); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); AABB *getAABB(Level *level, int x, int y, int z); bool blocksLight(); diff --git a/Minecraft.World/TripWireTile.cpp b/Minecraft.World/TripWireTile.cpp index ee302af2..da15453d 100644 --- a/Minecraft.World/TripWireTile.cpp +++ b/Minecraft.World/TripWireTile.cpp @@ -11,6 +11,38 @@ TripWireTile::TripWireTile(int id) : Tile(id, Material::decoration, isSolidRende this->setTicking(true); } +void TripWireTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int TripWireTile::defaultBlockState() +{ + return 0; +} + +int TripWireTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0xF) : 0; +} + +Tile::BlockState TripWireTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0xF); +} + +Tile::BlockState TripWireTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + int data = level->getData(x, y, z); + int state = 0; + if (shouldConnectTo(level, x, y, z, data, Direction::NORTH)) state |= 0x1; + if (shouldConnectTo(level, x, y, z, data, Direction::SOUTH)) state |= 0x2; + if (shouldConnectTo(level, x, y, z, data, Direction::EAST)) state |= 0x4; + if (shouldConnectTo(level, x, y, z, data, Direction::WEST)) state |= 0x8; + return Tile::BlockState(state); +} + int TripWireTile::getTickDelay(Level *level) { // 4J: Increased (x2); quick update caused problems with shared diff --git a/Minecraft.World/TripWireTile.h b/Minecraft.World/TripWireTile.h index 7880e664..7315cbd5 100644 --- a/Minecraft.World/TripWireTile.h +++ b/Minecraft.World/TripWireTile.h @@ -12,6 +12,11 @@ public: static const int MASK_DISARMED = 0x8; TripWireTile(int id); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); int getTickDelay(Level *level); AABB *getAABB(Level *level, int x, int y, int z); diff --git a/Minecraft.World/VineTile.cpp b/Minecraft.World/VineTile.cpp index 8f16a921..7110cc16 100644 --- a/Minecraft.World/VineTile.cpp +++ b/Minecraft.World/VineTile.cpp @@ -13,6 +13,32 @@ VineTile::VineTile(int id) : Tile(id, Material::replaceable_plant, isSolidRender setTicking(true); } +void VineTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int VineTile::defaultBlockState() +{ + return 0; +} + +int VineTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0xF) : 0; +} + +Tile::BlockState VineTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0xF); +} + +Tile::BlockState VineTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & 0xF); +} + void VineTile::updateDefaultShape() { setShape(0, 0, 0, 1, 1, 1); diff --git a/Minecraft.World/VineTile.h b/Minecraft.World/VineTile.h index bdea2cdc..38f089c1 100644 --- a/Minecraft.World/VineTile.h +++ b/Minecraft.World/VineTile.h @@ -14,6 +14,11 @@ public: public: VineTile(int id); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); virtual void updateDefaultShape(); virtual int getRenderShape(); virtual bool isSolidRender(bool isServerLevel = false); diff --git a/build-linux.sh b/build-linux.sh index d5357932..2da391a7 100755 --- a/build-linux.sh +++ b/build-linux.sh @@ -78,7 +78,7 @@ do_cmake_configure() { local winsdk="$XWIN_CACHE/splat" local toolchain toolchain="$(write_toolchain)" - local c_flags="/MT -Wno-non-pod-varargs -fms-compatibility -fms-extensions --target=x86_64-pc-windows-msvc \ + local c_flags="/MT -w -Wno-non-pod-varargs -fms-compatibility -fms-extensions --target=x86_64-pc-windows-msvc \ -imsvc $winsdk/crt/include \ -imsvc $winsdk/sdk/include/ucrt \ -imsvc $winsdk/sdk/include/um \