fix: item frames in tutorial + non-ugc worlds

still gotta fix it a little though
This commit is contained in:
Fireblade 2026-05-03 21:05:06 -04:00
parent a7cad496e3
commit bcb6fb9db1
5 changed files with 93 additions and 35 deletions

View file

@ -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<Entity> _itemframe, double x, double
int yt = itemFrame->yTile;
int zt = itemFrame->zTile + Direction::STEP_Z[itemFrame->dir];
glTranslatef(static_cast<float>(xt) - xOffs, static_cast<float>(yt) - yOffs, static_cast<float>(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<float>(xt) - xOffs - dx * back,
static_cast<float>(yt) - yOffs,
static_cast<float>(zt) - zOffs - dz * back
);
drawFrame(itemFrame);
drawItem(itemFrame);

View file

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

View file

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

View file

@ -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<byte>(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<int>(floor(x + 0.5f));
yTile = static_cast<int>(floor(y + 0.5f));
zTile = static_cast<int>(floor(z + 0.5f));
setDir(dir);
}
bool HangingEntity::repositionEntityAfterLoad()

View file

@ -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<Entity> causedBy)=0;