diff --git a/Minecraft.Client/ItemFrameRenderer.cpp b/Minecraft.Client/ItemFrameRenderer.cpp index be442176..8ac82dc0 100644 --- a/Minecraft.Client/ItemFrameRenderer.cpp +++ b/Minecraft.Client/ItemFrameRenderer.cpp @@ -18,6 +18,7 @@ #include "../Minecraft.World/net.minecraft.h" #include "CompassTexture.h" #include "Minimap.h" +#include "../Minecraft.World/Level.h" ResourceLocation ItemFrameRenderer::MAP_BACKGROUND_LOCATION = ResourceLocation(TN_MISC_MAPBG); @@ -41,7 +42,22 @@ void ItemFrameRenderer::render(shared_ptr _itemframe, double x, double int yt = itemFrame->yTile; int zt = itemFrame->zTile + Direction::STEP_Z[itemFrame->dir]; - glTranslatef(static_cast(xt) - xOffs, static_cast(yt) - yOffs, static_cast(zt) - zOffs); + float back = 0.0f; + + // set offset to 1 if the item frame is not placed by the player (FIXME AS IT DOESNT WORK PROPERLY) + if (itemFrame->level->isClientSide && !itemFrame->placedByPlayer) + { + back = 1.0f; + } + + int dx = Direction::STEP_X[itemFrame->dir]; + int dz = Direction::STEP_Z[itemFrame->dir]; + + glTranslatef( + static_cast(xt) - xOffs - dx * back, + static_cast(yt) - yOffs, + static_cast(zt) - zOffs - dz * back + ); drawFrame(itemFrame); drawItem(itemFrame); diff --git a/Minecraft.World/Direction.cpp b/Minecraft.World/Direction.cpp index c9ac93c7..f6e9fb1b 100644 --- a/Minecraft.World/Direction.cpp +++ b/Minecraft.World/Direction.cpp @@ -89,6 +89,16 @@ int Direction::getDirection(double xd, double zd) } } +int Direction::from2DDataValue(int param) +{ + return (param & 3); +} + +int Direction::getOpposite(int dir) +{ + return DIRECTION_OPPOSITE[dir & 3]; +} + int Direction::getDirection(int x0, int z0, int x1, int z1) { int xd = x0 - x1; diff --git a/Minecraft.World/Direction.h b/Minecraft.World/Direction.h index 8b8b91bf..d327d4ab 100644 --- a/Minecraft.World/Direction.h +++ b/Minecraft.World/Direction.h @@ -32,6 +32,9 @@ public: // for [direction][world-facing] it gives [tile-facing] static int RELATIVE_DIRECTION_FACING[4][6]; + static int getOpposite(int dir); + static int from2DDataValue(int param); + static int getDirection(double xd, double zd); static int getDirection(int x0, int z0, int x1, int z1); diff --git a/Minecraft.World/HangingEntity.cpp b/Minecraft.World/HangingEntity.cpp index 9aa57e86..90c87dd0 100644 --- a/Minecraft.World/HangingEntity.cpp +++ b/Minecraft.World/HangingEntity.cpp @@ -6,8 +6,8 @@ #include "net.minecraft.world.damagesource.h" #include "com.mojang.nbt.h" #include "HangingEntity.h" - - +#include "../Minecraft.Client/Minecraft.h" +#include "Level.h" void HangingEntity::_init(Level *level) { @@ -58,6 +58,7 @@ void HangingEntity::setDir(int dir) float x = xTile + 0.5f; float y = yTile + 0.5f; float z = zTile + 0.5f; + float originalX = x; float originalZ = z; float fOffs = 0.5f + 1.0f / 16.0f; @@ -65,10 +66,18 @@ void HangingEntity::setDir(int dir) fOffs = 0.5f + 1.0f / 32.0f; } - if (dir == Direction::NORTH) z -= fOffs; - if (dir == Direction::WEST) x -= fOffs; - if (dir == Direction::SOUTH) z += fOffs; - if (dir == Direction::EAST) x += fOffs; + int offset = 0; + + // set offset to 1 if player is stock world (not auto generated) (FIXME AS IT DOESNT WORK) + if (level->isClientSide && !placedByPlayer) + { + offset = 1; + } + + if (dir == Direction::NORTH) z -= fOffs - offset; + if (dir == Direction::WEST) x -= fOffs - offset; + if (dir == Direction::SOUTH) z += fOffs - offset; + if (dir == Direction::EAST) x += fOffs - offset; if (dir == Direction::NORTH) x -= offs(getWidth()); if (dir == Direction::WEST) z += offs(getWidth()); @@ -120,8 +129,9 @@ void HangingEntity::tick() checkInterval = 0; if (!removed && !survives()) { - remove(); - dropItem(nullptr); + // TODO: apply same non-player placed checks here + // remove(); + // dropItem(nullptr); } } } @@ -252,6 +262,7 @@ void HangingEntity::push(double xa, double ya, double za) void HangingEntity::addAdditonalSaveData(CompoundTag *tag) { + tag->putByte(L"PlacedByPlayer", placedByPlayer ? 1 : 0); tag->putByte(L"Direction", static_cast(dir)); tag->putInt(L"TileX", xTile); tag->putInt(L"TileY", yTile); @@ -277,34 +288,49 @@ void HangingEntity::addAdditonalSaveData(CompoundTag *tag) void HangingEntity::readAdditionalSaveData(CompoundTag *tag) { - if (tag->contains(L"Direction")) + if (tag->contains(L"TileX") && tag->contains(L"TileY") && tag->contains(L"TileZ")) + { + xTile = tag->getInt(L"TileX"); + yTile = tag->getInt(L"TileY"); + zTile = tag->getInt(L"TileZ"); + + 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")) { - dir = tag->getByte(L"Direction"); + placedByPlayer = tag->getByte(L"PlacedByPlayer") == 1; } - else - { - 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; - } - } - - xTile = static_cast(floor(x + 0.5f)); - yTile = static_cast(floor(y + 0.5f)); - zTile = static_cast(floor(z + 0.5f)); - - setDir(dir); } bool HangingEntity::repositionEntityAfterLoad() diff --git a/Minecraft.World/HangingEntity.h b/Minecraft.World/HangingEntity.h index 30d0a1bd..e6aa8c8d 100644 --- a/Minecraft.World/HangingEntity.h +++ b/Minecraft.World/HangingEntity.h @@ -20,6 +20,7 @@ protected: public: int dir; int xTile, yTile, zTile; + bool placedByPlayer = false; HangingEntity(Level *level); HangingEntity(Level *level, int xTile, int yTile, int zTile, int dir); @@ -39,6 +40,8 @@ public: virtual void addAdditonalSaveData(CompoundTag *tag); virtual void readAdditionalSaveData(CompoundTag *tag); + int getDirection(); + void getPos(Vec3i& out); virtual int getWidth()=0; virtual int getHeight()=0; virtual void dropItem(shared_ptr causedBy)=0;