diff --git a/Minecraft.Client/ClientConnection.cpp b/Minecraft.Client/ClientConnection.cpp index d13356f9..d0f97cee 100644 --- a/Minecraft.Client/ClientConnection.cpp +++ b/Minecraft.Client/ClientConnection.cpp @@ -561,7 +561,20 @@ void ClientConnection::handleAddEntity(shared_ptr packet) int iz = (int) z; app.DebugPrintf("ClientConnection ITEM_FRAME xyz %d,%d,%d\n",ix,iy,iz); } - e = std::make_shared(level, (int)x, (int)y, (int)z, packet->data); + { + int dir = packet->data & 0xFF; + bool placedByPlayer = (packet->data & 0x100) != 0; + e = std::make_shared(level, (int)x, (int)y, (int)z, dir); + shared_ptr frame = dynamic_pointer_cast(e); + if (frame != nullptr) + { + frame->placedByPlayer = placedByPlayer; + if (placedByPlayer) + { + frame->setDir(dir); + } + } + } packet->data = 0; setRot = false; break; @@ -815,6 +828,11 @@ void ClientConnection::handleAddGlobalEntity(shared_ptr p void ClientConnection::handleAddPainting(shared_ptr packet) { shared_ptr painting = std::make_shared(level, packet->x, packet->y, packet->z, packet->dir, packet->motive); + painting->placedByPlayer = packet->placedByPlayer; + if (packet->placedByPlayer) + { + painting->setDir(packet->dir); + } level->putEntity(packet->id, painting); m_trackedEntityIds.insert(packet->id); } diff --git a/Minecraft.Client/ItemFrameRenderer.cpp b/Minecraft.Client/ItemFrameRenderer.cpp index 8ac82dc0..83eca84e 100644 --- a/Minecraft.Client/ItemFrameRenderer.cpp +++ b/Minecraft.Client/ItemFrameRenderer.cpp @@ -44,7 +44,7 @@ void ItemFrameRenderer::render(shared_ptr _itemframe, double x, double float back = 0.0f; - // set offset to 1 if the item frame is not placed by the player (FIXME AS IT DOESNT WORK PROPERLY) + // set offset to 1 if the item frame is not placed by the player if (itemFrame->level->isClientSide && !itemFrame->placedByPlayer) { back = 1.0f; diff --git a/Minecraft.Client/TrackedEntity.cpp b/Minecraft.Client/TrackedEntity.cpp index 161c5b0c..bd475097 100644 --- a/Minecraft.Client/TrackedEntity.cpp +++ b/Minecraft.Client/TrackedEntity.cpp @@ -805,7 +805,12 @@ shared_ptr TrackedEntity::getAddEntityPacket() app.DebugPrintf("eTYPE_ITEM_FRAME xyz %d,%d,%d\n",ix,iy,iz); } - shared_ptr packet = std::make_shared(e, AddEntityPacket::ITEM_FRAME, frame->dir, yRotp, xRotp, xp, yp, zp); + int data = frame->dir & 0xFF; + if (frame->placedByPlayer) + { + data |= 0x100; + } + shared_ptr packet = std::make_shared(e, AddEntityPacket::ITEM_FRAME, data, yRotp, xRotp, xp, yp, zp); packet->x = Mth::floor(frame->xTile * 32.0f); packet->y = Mth::floor(frame->yTile * 32.0f); packet->z = Mth::floor(frame->zTile * 32.0f); diff --git a/Minecraft.World/AddPaintingPacket.cpp b/Minecraft.World/AddPaintingPacket.cpp index f574cbf2..1b3ec14b 100644 --- a/Minecraft.World/AddPaintingPacket.cpp +++ b/Minecraft.World/AddPaintingPacket.cpp @@ -15,6 +15,7 @@ AddPaintingPacket::AddPaintingPacket() z = 0; dir = 0; motive = L""; + placedByPlayer = false; } AddPaintingPacket::AddPaintingPacket(shared_ptr e) @@ -25,6 +26,7 @@ AddPaintingPacket::AddPaintingPacket(shared_ptr e) z = e->zTile; dir = e->dir; motive = e->motive->name; + placedByPlayer = e->placedByPlayer; } void AddPaintingPacket::read(DataInputStream *dis) //throws IOException @@ -35,6 +37,7 @@ void AddPaintingPacket::read(DataInputStream *dis) //throws IOException y = dis->readInt(); z = dis->readInt(); dir = dis->readInt(); + placedByPlayer = dis->readByte() != 0; } void AddPaintingPacket::write(DataOutputStream *dos) //throws IOException @@ -45,6 +48,7 @@ void AddPaintingPacket::write(DataOutputStream *dos) //throws IOException dos->writeInt(y); dos->writeInt(z); dos->writeInt(dir); + dos->writeByte(placedByPlayer ? 1 : 0); } void AddPaintingPacket::handle(PacketListener *listener) @@ -54,5 +58,5 @@ void AddPaintingPacket::handle(PacketListener *listener) int AddPaintingPacket::getEstimatedSize() { - return 24; + return 25; } diff --git a/Minecraft.World/AddPaintingPacket.h b/Minecraft.World/AddPaintingPacket.h index a50c1b77..e42c4863 100644 --- a/Minecraft.World/AddPaintingPacket.h +++ b/Minecraft.World/AddPaintingPacket.h @@ -12,6 +12,7 @@ public: int x, y, z; int dir; wstring motive; + bool placedByPlayer; public: AddPaintingPacket(); diff --git a/Minecraft.World/CompressedTileStorage.cpp b/Minecraft.World/CompressedTileStorage.cpp index c6ea725b..166f99a8 100644 --- a/Minecraft.World/CompressedTileStorage.cpp +++ b/Minecraft.World/CompressedTileStorage.cpp @@ -604,6 +604,7 @@ int CompressedTileStorage::get(int x, int y, int z) int block, tile; getBlockAndTile( &block, &tile, x, y, z ); + if (blockIndices[block] == 0) return 0; int indexType = blockIndices[block] & INDEX_TYPE_MASK; if( indexType == INDEX_TYPE_0_OR_8_BIT ) diff --git a/Minecraft.World/HangingEntity.cpp b/Minecraft.World/HangingEntity.cpp index 90c87dd0..16649396 100644 --- a/Minecraft.World/HangingEntity.cpp +++ b/Minecraft.World/HangingEntity.cpp @@ -68,7 +68,7 @@ void HangingEntity::setDir(int dir) int offset = 0; - // set offset to 1 if player is stock world (not auto generated) (FIXME AS IT DOESNT WORK) + // set offset to 1 if placed in stock world if (level->isClientSide && !placedByPlayer) { offset = 1; @@ -90,10 +90,10 @@ void HangingEntity::setDir(int dir) float ss = -(0.5f / 16.0f); if (this->GetType() == eTYPE_PAINTING) { fOffs = 0.5f + 1.0f / 16.0f; - if (dir == Direction::NORTH) originalZ -= fOffs; - if (dir == Direction::WEST) originalX -= fOffs; - if (dir == Direction::SOUTH) originalZ += fOffs; - if (dir == Direction::EAST) originalX += fOffs; + if (dir == Direction::NORTH) originalZ -= fOffs - offset; + if (dir == Direction::WEST) originalX -= fOffs - offset; + if (dir == Direction::SOUTH) originalZ += fOffs - offset; + if (dir == Direction::EAST) originalX += fOffs - offset; if (dir == Direction::NORTH) originalX -= offs(getWidth()); if (dir == Direction::WEST) originalZ += offs(getWidth()); if (dir == Direction::SOUTH) originalX += offs(getWidth()); @@ -127,11 +127,10 @@ void HangingEntity::tick() if (checkInterval++ == 20 * 5 && !level->isClientSide) { checkInterval = 0; - if (!removed && !survives()) + if (!removed && !survives() && placedByPlayer) { - // TODO: apply same non-player placed checks here - // remove(); - // dropItem(nullptr); + remove(); + dropItem(nullptr); } } } @@ -297,40 +296,39 @@ void HangingEntity::readAdditionalSaveData(CompoundTag *tag) setPos(xTile, yTile, zTile); } - if (tag->contains(L"Direction")) - { - dir = tag->getByte(L"Direction"); - setDir(dir); - return; - } - - if (tag->contains(L"Facing")) - { - int f = tag->getByte(L"Facing"); - dir = Direction::from2DDataValue(f); - - setDir(dir); - return; - } - - // fallback for legacy system - if (tag->contains(L"Dir")) - { - switch (tag->getByte(L"Dir")) - { - case 0: dir = Direction::NORTH; break; - case 1: dir = Direction::WEST; break; - case 2: dir = Direction::SOUTH; break; - case 3: dir = Direction::EAST; break; - } - - setDir(dir); - } - if (tag->contains(L"PlacedByPlayer")) { placedByPlayer = tag->getByte(L"PlacedByPlayer") == 1; } + + bool hasDir = false; + if (tag->contains(L"Direction")) + { + dir = tag->getByte(L"Direction"); + hasDir = true; + } + else if (tag->contains(L"Facing")) + { + int f = tag->getByte(L"Facing"); + dir = Direction::from2DDataValue(f); + hasDir = true; + } + else if (tag->contains(L"Dir")) + { + switch (tag->getByte(L"Dir")) + { + case 0: dir = Direction::NORTH; break; + case 1: dir = Direction::WEST; break; + case 2: dir = Direction::SOUTH; break; + case 3: dir = Direction::EAST; break; + } + hasDir = true; + } + + if (hasDir) + { + setDir(dir); + } } bool HangingEntity::repositionEntityAfterLoad() diff --git a/Minecraft.World/HangingEntityItem.cpp b/Minecraft.World/HangingEntityItem.cpp index 97ddb31d..51f4d3cb 100644 --- a/Minecraft.World/HangingEntityItem.cpp +++ b/Minecraft.World/HangingEntityItem.cpp @@ -67,6 +67,7 @@ shared_ptr HangingEntityItem::createEntity(Level *level, int x, i if (eType == eTYPE_PAINTING) { shared_ptr painting = std::make_shared(level, x, y, z, dir); + painting->placedByPlayer = true; #ifndef _CONTENT_PACKAGE if (app.DebugArtToolsOn() && auxValue > 0) @@ -84,6 +85,8 @@ shared_ptr HangingEntityItem::createEntity(Level *level, int x, i else if (eType == eTYPE_ITEM_FRAME) { shared_ptr itemFrame = std::make_shared(level, x, y, z, dir); + itemFrame->placedByPlayer = true; + itemFrame->setDir(dir); return dynamic_pointer_cast (itemFrame); }