Add item frame saving.
This commit is contained in:
parent
cf13739288
commit
7ac7304c91
@ -60,6 +60,8 @@ if (NOT MSVC)
|
||||
Entities/ProjectileEntity.h
|
||||
Entities/TNTEntity.h
|
||||
Entities/ExpOrb.h
|
||||
Entities/HangingEntity.h
|
||||
Entities/ItemFrame.h
|
||||
Generating/ChunkDesc.h
|
||||
Group.h
|
||||
Inventory.h
|
||||
|
53
src/Entities/HangingEntity.cpp
Normal file
53
src/Entities/HangingEntity.cpp
Normal file
@ -0,0 +1,53 @@
|
||||
|
||||
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
||||
|
||||
#include "HangingEntity.h"
|
||||
#include "ClientHandle.h"
|
||||
#include "Player.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cHangingEntity::cHangingEntity(eEntityType a_EntityType, eBlockFace a_BlockFace, double a_X, double a_Y, double a_Z)
|
||||
: cEntity(a_EntityType, a_X, a_Y, a_Z, 0.8, 0.8)
|
||||
, m_BlockFace(a_BlockFace)
|
||||
{
|
||||
SetMaxHealth(1);
|
||||
SetHealth(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cHangingEntity::SpawnOn(cClientHandle & a_ClientHandle)
|
||||
{
|
||||
int Dir = 0;
|
||||
|
||||
// The client uses different values for item frame directions and block faces. Our constants are for the block faces, so we convert them here to item frame faces
|
||||
switch (m_BlockFace)
|
||||
{
|
||||
case BLOCK_FACE_ZP: break; // Initialised to zero
|
||||
case BLOCK_FACE_ZM: Dir = 2; break;
|
||||
case BLOCK_FACE_XM: Dir = 1; break;
|
||||
case BLOCK_FACE_XP: Dir = 3; break;
|
||||
default: ASSERT(!"Unhandled block face when trying to spawn item frame!"); return;
|
||||
}
|
||||
|
||||
if ((Dir == 0) || (Dir == 2)) // Probably a client bug, but two directions are flipped and contrary to the norm, so we do -180
|
||||
{
|
||||
SetYaw((Dir * 90) - 180);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetYaw(Dir * 90);
|
||||
}
|
||||
|
||||
a_ClientHandle.SendSpawnObject(*this, 71, Dir, (Byte)GetYaw(), (Byte)GetPitch());
|
||||
a_ClientHandle.SendEntityMetadata(*this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
49
src/Entities/HangingEntity.h
Normal file
49
src/Entities/HangingEntity.h
Normal file
@ -0,0 +1,49 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Entity.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// tolua_begin
|
||||
class cHangingEntity :
|
||||
public cEntity
|
||||
{
|
||||
// tolua_end
|
||||
typedef cEntity super;
|
||||
|
||||
public:
|
||||
|
||||
CLASS_PROTODEF(cHangingEntity);
|
||||
|
||||
cHangingEntity(eEntityType a_EntityType, eBlockFace a_BlockFace, double a_X, double a_Y, double a_Z);
|
||||
|
||||
/** Returns the orientation from the hanging entity */
|
||||
eBlockFace GetDirection() const { return m_BlockFace; } // tolua_export
|
||||
|
||||
/** Set the orientation from the hanging entity */
|
||||
void SetDirection(eBlockFace a_BlockFace) { m_BlockFace = a_BlockFace; } // tolua_export
|
||||
|
||||
/** Returns the X coord. */
|
||||
int GetTileX() const { return POSX_TOINT; } // tolua_export
|
||||
|
||||
/** Returns the Y coord. */
|
||||
int GetTileY() const { return POSY_TOINT; } // tolua_export
|
||||
|
||||
/** Returns the Z coord. */
|
||||
int GetTileZ() const { return POSZ_TOINT; } // tolua_export
|
||||
|
||||
private:
|
||||
|
||||
virtual void SpawnOn(cClientHandle & a_ClientHandle) override;
|
||||
virtual void Tick(float a_Dt, cChunk & a_Chunk) override {};
|
||||
|
||||
eBlockFace m_BlockFace;
|
||||
|
||||
}; // tolua_export
|
||||
|
||||
|
||||
|
||||
|
@ -10,43 +10,10 @@
|
||||
|
||||
|
||||
cItemFrame::cItemFrame(eBlockFace a_BlockFace, double a_X, double a_Y, double a_Z)
|
||||
: cEntity(etItemFrame, a_X, a_Y, a_Z, 0.8, 0.8),
|
||||
m_BlockFace(a_BlockFace),
|
||||
m_Item(E_BLOCK_AIR),
|
||||
m_Rotation(0)
|
||||
: cHangingEntity(etItemFrame, a_BlockFace, a_X, a_Y, a_Z)
|
||||
, m_Item(E_BLOCK_AIR)
|
||||
, m_Rotation(0)
|
||||
{
|
||||
SetMaxHealth(1);
|
||||
SetHealth(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cItemFrame::SpawnOn(cClientHandle & a_ClientHandle)
|
||||
{
|
||||
int Dir = 0;
|
||||
|
||||
// The client uses different values for item frame directions and block faces. Our constants are for the block faces, so we convert them here to item frame faces
|
||||
switch (m_BlockFace)
|
||||
{
|
||||
case BLOCK_FACE_ZP: break; // Initialised to zero
|
||||
case BLOCK_FACE_ZM: Dir = 2; break;
|
||||
case BLOCK_FACE_XM: Dir = 1; break;
|
||||
case BLOCK_FACE_XP: Dir = 3; break;
|
||||
default: ASSERT(!"Unhandled block face when trying to spawn item frame!"); return;
|
||||
}
|
||||
|
||||
if ((Dir == 0) || (Dir == 2)) // Probably a client bug, but two directions are flipped and contrary to the norm, so we do -180
|
||||
{
|
||||
SetYaw((Dir * 90) - 180);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetYaw(Dir * 90);
|
||||
}
|
||||
|
||||
a_ClientHandle.SendSpawnObject(*this, 71, Dir, (Byte)GetYaw(), (Byte)GetPitch());
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Entity.h"
|
||||
#include "HangingEntity.h"
|
||||
|
||||
|
||||
|
||||
@ -9,10 +9,10 @@
|
||||
|
||||
// tolua_begin
|
||||
class cItemFrame :
|
||||
public cEntity
|
||||
public cHangingEntity
|
||||
{
|
||||
// tolua_end
|
||||
typedef cEntity super;
|
||||
typedef cHangingEntity super;
|
||||
|
||||
public:
|
||||
|
||||
@ -20,18 +20,24 @@ public:
|
||||
|
||||
cItemFrame(eBlockFace a_BlockFace, double a_X, double a_Y, double a_Z);
|
||||
|
||||
const cItem & GetItem(void) { return m_Item; }
|
||||
Byte GetRotation(void) const { return m_Rotation; }
|
||||
/** Returns the item in the frame */
|
||||
const cItem & GetItem(void) { return m_Item; } // tolua_export
|
||||
|
||||
/** Set the item in the frame */
|
||||
void SetItem(cItem & a_Item) { m_Item = a_Item; }; // tolua_export
|
||||
|
||||
/** Returns the rotation from the item in the frame */
|
||||
Byte GetRotation(void) const { return m_Rotation; } // tolua_export
|
||||
|
||||
/** Set the rotation from the item in the frame */
|
||||
void SetRotation(Byte a_Rotation) { m_Rotation = a_Rotation; } // tolua_export
|
||||
|
||||
private:
|
||||
|
||||
virtual void SpawnOn(cClientHandle & a_ClientHandle) override;
|
||||
virtual void OnRightClicked(cPlayer & a_Player) override;
|
||||
virtual void Tick(float a_Dt, cChunk & a_Chunk) override {};
|
||||
virtual void KilledBy(cEntity * a_Killer) override;
|
||||
virtual void GetDrops(cItems & a_Items, cEntity * a_Killer) override;
|
||||
|
||||
eBlockFace m_BlockFace;
|
||||
cItem m_Item;
|
||||
Byte m_Rotation;
|
||||
|
||||
|
@ -30,6 +30,8 @@
|
||||
#include "../Entities/ProjectileEntity.h"
|
||||
#include "../Entities/TNTEntity.h"
|
||||
#include "../Entities/ExpOrb.h"
|
||||
#include "../Entities/HangingEntity.h"
|
||||
#include "../Entities/ItemFrame.h"
|
||||
|
||||
#include "../Mobs/Monster.h"
|
||||
#include "../Mobs/Bat.h"
|
||||
@ -585,6 +587,25 @@ void cNBTChunkSerializer::AddProjectileEntity(cProjectileEntity * a_Projectile)
|
||||
|
||||
|
||||
|
||||
void cNBTChunkSerializer::AddHangingEntity(cHangingEntity * a_Hanging)
|
||||
{
|
||||
m_Writer.AddByte("Direction", (unsigned char)a_Hanging->GetDirection());
|
||||
m_Writer.AddInt("TileX", a_Hanging->GetTileX());
|
||||
m_Writer.AddInt("TileY", a_Hanging->GetTileY());
|
||||
m_Writer.AddInt("TileZ", a_Hanging->GetTileZ());
|
||||
switch (a_Hanging->GetDirection())
|
||||
{
|
||||
case 0: m_Writer.AddByte("Dir", (unsigned char)2); break;
|
||||
case 1: m_Writer.AddByte("Dir", (unsigned char)1); break;
|
||||
case 2: m_Writer.AddByte("Dir", (unsigned char)0); break;
|
||||
case 3: m_Writer.AddByte("Dir", (unsigned char)3); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cNBTChunkSerializer::AddTNTEntity(cTNTEntity * a_TNT)
|
||||
{
|
||||
m_Writer.BeginCompound("");
|
||||
@ -611,6 +632,21 @@ void cNBTChunkSerializer::AddExpOrbEntity(cExpOrb* a_ExpOrb)
|
||||
|
||||
|
||||
|
||||
void cNBTChunkSerializer::AddItemFrameEntity(cItemFrame * a_ItemFrame)
|
||||
{
|
||||
m_Writer.BeginCompound("");
|
||||
AddBasicEntity(a_ItemFrame, "ItemFrame");
|
||||
AddHangingEntity(a_ItemFrame);
|
||||
AddItem(a_ItemFrame->GetItem(), -1, "Item");
|
||||
m_Writer.AddByte("ItemRotation", (unsigned char)a_ItemFrame->GetRotation());
|
||||
m_Writer.AddFloat("ItemDropChance", 1.0F);
|
||||
m_Writer.EndCompound();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cNBTChunkSerializer::AddMinecartChestContents(cMinecartWithChest * a_Minecart)
|
||||
{
|
||||
m_Writer.BeginList("Items", TAG_Compound);
|
||||
@ -692,7 +728,7 @@ void cNBTChunkSerializer::Entity(cEntity * a_Entity)
|
||||
case cEntity::etProjectile: AddProjectileEntity ((cProjectileEntity *)a_Entity); break;
|
||||
case cEntity::etTNT: AddTNTEntity ((cTNTEntity *) a_Entity); break;
|
||||
case cEntity::etExpOrb: AddExpOrbEntity ((cExpOrb *) a_Entity); break;
|
||||
case cEntity::etItemFrame: /* TODO */ break;
|
||||
case cEntity::etItemFrame: AddItemFrameEntity ((cItemFrame *) a_Entity); break;
|
||||
case cEntity::etPainting: /* TODO */ break;
|
||||
case cEntity::etPlayer: return; // Players aren't saved into the world
|
||||
default:
|
||||
|
@ -43,6 +43,8 @@ class cItemGrid;
|
||||
class cProjectileEntity;
|
||||
class cTNTEntity;
|
||||
class cExpOrb;
|
||||
class cHangingEntity;
|
||||
class cItemFrame;
|
||||
|
||||
|
||||
|
||||
@ -109,8 +111,10 @@ protected:
|
||||
void AddMonsterEntity (cMonster * a_Monster);
|
||||
void AddPickupEntity (cPickup * a_Pickup);
|
||||
void AddProjectileEntity (cProjectileEntity * a_Projectile);
|
||||
void AddHangingEntity (cHangingEntity * a_Hanging);
|
||||
void AddTNTEntity (cTNTEntity * a_TNT);
|
||||
void AddExpOrbEntity (cExpOrb * a_ExpOrb);
|
||||
void AddItemFrameEntity (cItemFrame * a_ItemFrame);
|
||||
|
||||
void AddMinecartChestContents(cMinecartWithChest * a_Minecart);
|
||||
|
||||
|
@ -38,6 +38,8 @@
|
||||
#include "../Entities/ProjectileEntity.h"
|
||||
#include "../Entities/TNTEntity.h"
|
||||
#include "../Entities/ExpOrb.h"
|
||||
#include "../Entities/HangingEntity.h"
|
||||
#include "../Entities/ItemFrame.h"
|
||||
|
||||
|
||||
|
||||
@ -1101,6 +1103,10 @@ void cWSSAnvil::LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a
|
||||
{
|
||||
LoadExpOrbFromNBT(a_Entities, a_NBT, a_EntityTagIdx);
|
||||
}
|
||||
else if (strncmp(a_IDTag, "ItemFrame", a_IDTagLength) == 0)
|
||||
{
|
||||
LoadItemFrameFromNBT(a_Entities, a_NBT, a_EntityTagIdx);
|
||||
}
|
||||
else if (strncmp(a_IDTag, "Arrow", a_IDTagLength) == 0)
|
||||
{
|
||||
LoadArrowFromNBT(a_Entities, a_NBT, a_EntityTagIdx);
|
||||
@ -1480,6 +1486,85 @@ void cWSSAnvil::LoadExpOrbFromNBT(cEntityList & a_Entities, const cParsedNBT & a
|
||||
|
||||
|
||||
|
||||
void cWSSAnvil::LoadHangingFromNBT(cHangingEntity & a_Hanging, const cParsedNBT & a_NBT, int a_TagIdx)
|
||||
{
|
||||
int Direction = a_NBT.FindChildByName(a_TagIdx, "Direction");
|
||||
if (Direction > 0)
|
||||
{
|
||||
a_Hanging.SetDirection(static_cast<eBlockFace>((int)a_NBT.GetByte(Direction)));
|
||||
}
|
||||
else
|
||||
{
|
||||
Direction = a_NBT.FindChildByName(a_TagIdx, "Dir");
|
||||
if (Direction > 0)
|
||||
{
|
||||
switch ((int)a_NBT.GetByte(Direction))
|
||||
{
|
||||
case 0: a_Hanging.SetDirection(BLOCK_FACE_NORTH); break;
|
||||
case 1: a_Hanging.SetDirection(BLOCK_FACE_TOP); break;
|
||||
case 2: a_Hanging.SetDirection(BLOCK_FACE_BOTTOM); break;
|
||||
case 3: a_Hanging.SetDirection(BLOCK_FACE_SOUTH); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LOG("LALALAL.");
|
||||
int TileX = a_NBT.FindChildByName(a_TagIdx, "TileX");
|
||||
int TileY = a_NBT.FindChildByName(a_TagIdx, "TileY");
|
||||
int TileZ = a_NBT.FindChildByName(a_TagIdx, "TileZ");
|
||||
if ((TileX > 0) && (TileY > 0) && (TileZ > 0))
|
||||
{
|
||||
LOG("YO!");
|
||||
a_Hanging.SetPosition(
|
||||
(double)a_NBT.GetInt(TileX),
|
||||
(double)a_NBT.GetInt(TileY),
|
||||
(double)a_NBT.GetInt(TileZ)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWSSAnvil::LoadItemFrameFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx)
|
||||
{
|
||||
// Load item:
|
||||
int ItemTag = a_NBT.FindChildByName(a_TagIdx, "Item");
|
||||
if ((ItemTag < 0) || (a_NBT.GetType(ItemTag) != TAG_Compound))
|
||||
{
|
||||
return;
|
||||
}
|
||||
cItem Item;
|
||||
if (!LoadItemFromNBT(Item, a_NBT, ItemTag))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::auto_ptr<cItemFrame> ItemFrame(new cItemFrame(BLOCK_FACE_NONE, 0.0, 0.0, 0.0));
|
||||
if (!LoadEntityBaseFromNBT(*ItemFrame.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
return;
|
||||
}
|
||||
ItemFrame->SetItem(Item);
|
||||
|
||||
LOG("BAUM! %d", Item.m_ItemType);
|
||||
LoadHangingFromNBT(*ItemFrame.get(), a_NBT, a_TagIdx);
|
||||
|
||||
// Load Rotation:
|
||||
int Rotation = a_NBT.FindChildByName(a_TagIdx, "ItemRotation");
|
||||
if (Rotation > 0)
|
||||
{
|
||||
ItemFrame->SetRotation((Byte)a_NBT.GetByte(Rotation));
|
||||
}
|
||||
|
||||
a_Entities.push_back(ItemFrame.release());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWSSAnvil::LoadArrowFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx)
|
||||
{
|
||||
std::auto_ptr<cArrowEntity> Arrow(new cArrowEntity(NULL, 0, 0, 0, Vector3d(0, 0, 0)));
|
||||
|
@ -20,6 +20,7 @@
|
||||
class cItemGrid;
|
||||
|
||||
class cProjectileEntity;
|
||||
class cHangingEntity;
|
||||
|
||||
|
||||
|
||||
@ -151,6 +152,8 @@ protected:
|
||||
void LoadPickupFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
void LoadTNTFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
void LoadExpOrbFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
void LoadHangingFromNBT (cHangingEntity & a_Hanging,const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
void LoadItemFrameFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
|
||||
void LoadMinecartRFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
void LoadMinecartCFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
|
Loading…
Reference in New Issue
Block a user