feat: blockstates

still a work in progress
This commit is contained in:
Fireblade 2026-05-02 15:14:48 -04:00
parent fc35ef155b
commit d89fadff68
80 changed files with 2249 additions and 2 deletions

View file

@ -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"

View file

@ -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 <Common/UI/UI.h>
#include "../Minecraft.World/Tile.h"
#include "../Minecraft.World/BlockStateDecoderRegistry.h"
#include "../Minecraft.World/BlockStateDecoder.h"
#include <map>
#include <cwctype>
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<std::wstring, std::wstring> 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);

View file

@ -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 <sstream>
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();

View file

@ -0,0 +1,19 @@
#pragma once
#include <string>
#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);
}

View file

@ -0,0 +1,35 @@
#include "BlockStateDecoderRegistry.h"
#include <unordered_map>
#include <mutex>
namespace BlockStateDecoderRegistry {
static std::unordered_map<int, DecoderFn> *g_map = nullptr;
static std::mutex g_mapMutex;
static void ensureMap()
{
if (!g_map) g_map = new std::unordered_map<int, DecoderFn>();
}
void registerDecoder(int tileId, DecoderFn fn)
{
std::lock_guard<std::mutex> l(g_mapMutex);
ensureMap();
(*g_map)[tileId] = fn;
}
std::wstring decode(int tileId, int composite)
{
std::lock_guard<std::mutex> 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"";
}
}
}

View file

@ -0,0 +1,12 @@
#pragma once
#include <string>
#include <functional>
namespace BlockStateDecoderRegistry
{
using DecoderFn = std::function<std::wstring(int)>;
void registerDecoder(int tileId, DecoderFn fn);
std::wstring decode(int tileId, int composite);
}

View file

@ -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;

View file

@ -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<TileEntity> newTileEntity(Level *level);

View file

@ -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);

View file

@ -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();

View file

@ -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

View file

@ -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))

View file

@ -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);

View file

@ -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];

View file

@ -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);

View file

@ -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()
{

View file

@ -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:

View file

@ -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> 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;
}

View file

@ -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> 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> player, int clickedFace, float clickX, float clickY, float clickZ, bool soundOnly = false);
};

View file

@ -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;

View file

@ -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);

View file

@ -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

View file

@ -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<Entity> source);
virtual void updateShape(LevelSource *level, int x, int y, int z, int forceData = -1, shared_ptr<TileEntity> forceEntity = shared_ptr<TileEntity>()); // 4J added forceData, forceEntity param
virtual bool isSolidRender(bool isServerLevel = false);

View file

@ -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);

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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()
{

View file

@ -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,

View file

@ -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;

View file

@ -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);

View file

@ -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<TileEntity> forceEntity)
{
setShape(0, 0, 0, 1, 1, 1);

View file

@ -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<TileEntity> forceEntity = shared_ptr<TileEntity>());
virtual void addAABBs(Level *level, int x, int y, int z, AABB *box, AABBList *boxes, shared_ptr<Entity> source);
virtual int getPlacedOnFaceDataValue(Level *level, int x, int y, int z, int face, float clickX, float clickY, float clickZ, int itemValue);

View file

@ -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

View file

@ -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);

View file

@ -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)

View file

@ -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> player);
virtual bool use(Level *level, int x, int y, int z, shared_ptr<Player> player, int clickedFace, float clickX, float clickY, float clickZ, bool soundOnly = false); // 4J added soundOnly param

View file

@ -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;

View file

@ -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);

View file

@ -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()
{

View file

@ -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

View file

@ -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()
{

View file

@ -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

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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> player);

View file

@ -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()
{

View file

@ -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:

View file

@ -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> player, int clickedFace, float clickX, float clickY, float clickZ, bool soundOnly)
{
if (soundOnly) return false;

View file

@ -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> player, int clickedFace, float clickX, float clickY, float clickZ, bool soundOnly = false);
protected:

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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;
}

View file

@ -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);
};

View file

@ -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;

View file

@ -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:

View file

@ -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()
{

View file

@ -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);

View file

@ -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()
{

View file

@ -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;

View file

@ -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)

View file

@ -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();

View file

@ -287,6 +287,45 @@ void Tile::ReleaseThreadStorage()
ThreadStorage *tls = static_cast<ThreadStorage *>(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)
{

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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:

View file

@ -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;

View file

@ -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();

View file

@ -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

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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 \