Merge pull request #697 from Howaner/Skull
Add Skulls/Heads to MCServer
This commit is contained in:
commit
87db4b6a90
@ -22,6 +22,7 @@
|
|||||||
#include "../BlockEntities/FurnaceEntity.h"
|
#include "../BlockEntities/FurnaceEntity.h"
|
||||||
#include "../BlockEntities/HopperEntity.h"
|
#include "../BlockEntities/HopperEntity.h"
|
||||||
#include "../BlockEntities/NoteEntity.h"
|
#include "../BlockEntities/NoteEntity.h"
|
||||||
|
#include "../BlockEntities/MobHeadEntity.h"
|
||||||
#include "md5/md5.h"
|
#include "md5/md5.h"
|
||||||
#include "../LineBlockTracer.h"
|
#include "../LineBlockTracer.h"
|
||||||
#include "../WorldStorage/SchematicFileSerializer.h"
|
#include "../WorldStorage/SchematicFileSerializer.h"
|
||||||
@ -2416,6 +2417,7 @@ void ManualBindings::Bind(lua_State * tolua_S)
|
|||||||
tolua_function(tolua_S, "DoWithFurnaceAt", tolua_DoWithXYZ<cWorld, cFurnaceEntity, &cWorld::DoWithFurnaceAt>);
|
tolua_function(tolua_S, "DoWithFurnaceAt", tolua_DoWithXYZ<cWorld, cFurnaceEntity, &cWorld::DoWithFurnaceAt>);
|
||||||
tolua_function(tolua_S, "DoWithNoteBlockAt", tolua_DoWithXYZ<cWorld, cNoteEntity, &cWorld::DoWithNoteBlockAt>);
|
tolua_function(tolua_S, "DoWithNoteBlockAt", tolua_DoWithXYZ<cWorld, cNoteEntity, &cWorld::DoWithNoteBlockAt>);
|
||||||
tolua_function(tolua_S, "DoWithCommandBlockAt", tolua_DoWithXYZ<cWorld, cCommandBlockEntity, &cWorld::DoWithCommandBlockAt>);
|
tolua_function(tolua_S, "DoWithCommandBlockAt", tolua_DoWithXYZ<cWorld, cCommandBlockEntity, &cWorld::DoWithCommandBlockAt>);
|
||||||
|
tolua_function(tolua_S, "DoWithMobHeadBlockAt", tolua_DoWithXYZ<cWorld, cMobHeadEntity, &cWorld::DoWithMobHeadBlockAt>);
|
||||||
tolua_function(tolua_S, "DoWithPlayer", tolua_DoWith< cWorld, cPlayer, &cWorld::DoWithPlayer>);
|
tolua_function(tolua_S, "DoWithPlayer", tolua_DoWith< cWorld, cPlayer, &cWorld::DoWithPlayer>);
|
||||||
tolua_function(tolua_S, "FindAndDoWithPlayer", tolua_DoWith< cWorld, cPlayer, &cWorld::FindAndDoWithPlayer>);
|
tolua_function(tolua_S, "FindAndDoWithPlayer", tolua_DoWith< cWorld, cPlayer, &cWorld::FindAndDoWithPlayer>);
|
||||||
tolua_function(tolua_S, "ForEachBlockEntityInChunk", tolua_ForEachInChunk<cWorld, cBlockEntity, &cWorld::ForEachBlockEntityInChunk>);
|
tolua_function(tolua_S, "ForEachBlockEntityInChunk", tolua_ForEachInChunk<cWorld, cBlockEntity, &cWorld::ForEachBlockEntityInChunk>);
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "JukeboxEntity.h"
|
#include "JukeboxEntity.h"
|
||||||
#include "NoteEntity.h"
|
#include "NoteEntity.h"
|
||||||
#include "SignEntity.h"
|
#include "SignEntity.h"
|
||||||
|
#include "MobHeadEntity.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -29,6 +30,7 @@ cBlockEntity * cBlockEntity::CreateByBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE
|
|||||||
case E_BLOCK_DISPENSER: return new cDispenserEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
|
case E_BLOCK_DISPENSER: return new cDispenserEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
|
||||||
case E_BLOCK_DROPPER: return new cDropperEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
|
case E_BLOCK_DROPPER: return new cDropperEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
|
||||||
case E_BLOCK_ENDER_CHEST: return new cEnderChestEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
|
case E_BLOCK_ENDER_CHEST: return new cEnderChestEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
|
||||||
|
case E_BLOCK_HEAD: return new cMobHeadEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
|
||||||
case E_BLOCK_LIT_FURNACE: return new cFurnaceEntity (a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_World);
|
case E_BLOCK_LIT_FURNACE: return new cFurnaceEntity (a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_World);
|
||||||
case E_BLOCK_FURNACE: return new cFurnaceEntity (a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_World);
|
case E_BLOCK_FURNACE: return new cFurnaceEntity (a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_World);
|
||||||
case E_BLOCK_HOPPER: return new cHopperEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
|
case E_BLOCK_HOPPER: return new cHopperEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
|
||||||
|
108
src/BlockEntities/MobHeadEntity.cpp
Normal file
108
src/BlockEntities/MobHeadEntity.cpp
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
|
||||||
|
// MobHeadEntity.cpp
|
||||||
|
|
||||||
|
// Implements the cMobHeadEntity class representing a single skull/head in the world
|
||||||
|
|
||||||
|
#include "Globals.h"
|
||||||
|
#include "json/json.h"
|
||||||
|
#include "MobHeadEntity.h"
|
||||||
|
#include "../Entities/Player.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
cMobHeadEntity::cMobHeadEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) :
|
||||||
|
super(E_BLOCK_HEAD, a_BlockX, a_BlockY, a_BlockZ, a_World),
|
||||||
|
m_Owner("")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cMobHeadEntity::UsedBy(cPlayer * a_Player)
|
||||||
|
{
|
||||||
|
UNUSED(a_Player);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cMobHeadEntity::SetType(const eMobHeadType & a_Type)
|
||||||
|
{
|
||||||
|
if ((!m_Owner.empty()) && (a_Type != SKULL_TYPE_PLAYER))
|
||||||
|
{
|
||||||
|
m_Owner = "";
|
||||||
|
}
|
||||||
|
m_Type = a_Type;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cMobHeadEntity::SetRotation(eMobHeadRotation a_Rotation)
|
||||||
|
{
|
||||||
|
m_Rotation = a_Rotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cMobHeadEntity::SetOwner(const AString & a_Owner)
|
||||||
|
{
|
||||||
|
if ((a_Owner.length() > 16) || (m_Type != SKULL_TYPE_PLAYER))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_Owner = a_Owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cMobHeadEntity::SendTo(cClientHandle & a_Client)
|
||||||
|
{
|
||||||
|
a_Client.SendUpdateBlockEntity(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cMobHeadEntity::LoadFromJson(const Json::Value & a_Value)
|
||||||
|
{
|
||||||
|
m_PosX = a_Value.get("x", 0).asInt();
|
||||||
|
m_PosY = a_Value.get("y", 0).asInt();
|
||||||
|
m_PosZ = a_Value.get("z", 0).asInt();
|
||||||
|
|
||||||
|
m_Type = static_cast<eMobHeadType>(a_Value.get("Type", 0).asInt());
|
||||||
|
m_Rotation = static_cast<eMobHeadRotation>(a_Value.get("Rotation", 0).asInt());
|
||||||
|
m_Owner = a_Value.get("Owner", "").asString();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cMobHeadEntity::SaveToJson(Json::Value & a_Value)
|
||||||
|
{
|
||||||
|
a_Value["x"] = m_PosX;
|
||||||
|
a_Value["y"] = m_PosY;
|
||||||
|
a_Value["z"] = m_PosZ;
|
||||||
|
|
||||||
|
a_Value["Type"] = m_Type;
|
||||||
|
a_Value["Rotation"] = m_Rotation;
|
||||||
|
a_Value["Owner"] = m_Owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
79
src/BlockEntities/MobHeadEntity.h
Normal file
79
src/BlockEntities/MobHeadEntity.h
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
// MobHeadEntity.h
|
||||||
|
|
||||||
|
// Declares the cMobHeadEntity class representing a single skull/head in the world
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "BlockEntity.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace Json
|
||||||
|
{
|
||||||
|
class Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// tolua_begin
|
||||||
|
|
||||||
|
class cMobHeadEntity :
|
||||||
|
public cBlockEntity
|
||||||
|
{
|
||||||
|
typedef cBlockEntity super;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// tolua_end
|
||||||
|
|
||||||
|
/** Creates a new mob head entity at the specified block coords. a_World may be NULL */
|
||||||
|
cMobHeadEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
|
||||||
|
|
||||||
|
bool LoadFromJson( const Json::Value& a_Value );
|
||||||
|
virtual void SaveToJson(Json::Value& a_Value ) override;
|
||||||
|
|
||||||
|
// tolua_begin
|
||||||
|
|
||||||
|
/** Set the Type */
|
||||||
|
void SetType(const eMobHeadType & a_SkullType);
|
||||||
|
|
||||||
|
/** Set the Rotation */
|
||||||
|
void SetRotation(eMobHeadRotation a_Rotation);
|
||||||
|
|
||||||
|
/** Set the Player Name for Mobheads with Player type */
|
||||||
|
void SetOwner(const AString & a_Owner);
|
||||||
|
|
||||||
|
/** Get the Type */
|
||||||
|
eMobHeadType GetType(void) const { return m_Type; }
|
||||||
|
|
||||||
|
/** Get the Rotation */
|
||||||
|
eMobHeadRotation GetRotation(void) const { return m_Rotation; }
|
||||||
|
|
||||||
|
/** Get the setted Player Name */
|
||||||
|
AString GetOwner(void) const { return m_Owner; }
|
||||||
|
|
||||||
|
// tolua_end
|
||||||
|
|
||||||
|
virtual void UsedBy(cPlayer * a_Player) override;
|
||||||
|
virtual void SendTo(cClientHandle & a_Client) override;
|
||||||
|
|
||||||
|
static const char * GetClassStatic(void) { return "cMobHeadEntity"; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
eMobHeadType m_Type;
|
||||||
|
eMobHeadRotation m_Rotation;
|
||||||
|
AString m_Owner;
|
||||||
|
} ; // tolua_export
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -34,6 +34,7 @@
|
|||||||
#include "BlockGlass.h"
|
#include "BlockGlass.h"
|
||||||
#include "BlockGlowstone.h"
|
#include "BlockGlowstone.h"
|
||||||
#include "BlockGravel.h"
|
#include "BlockGravel.h"
|
||||||
|
#include "BlockMobHead.h"
|
||||||
#include "BlockHopper.h"
|
#include "BlockHopper.h"
|
||||||
#include "BlockIce.h"
|
#include "BlockIce.h"
|
||||||
#include "BlockLadder.h"
|
#include "BlockLadder.h"
|
||||||
@ -146,6 +147,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
|
|||||||
case E_BLOCK_GRASS: return new cBlockDirtHandler (a_BlockType);
|
case E_BLOCK_GRASS: return new cBlockDirtHandler (a_BlockType);
|
||||||
case E_BLOCK_GRAVEL: return new cBlockGravelHandler (a_BlockType);
|
case E_BLOCK_GRAVEL: return new cBlockGravelHandler (a_BlockType);
|
||||||
case E_BLOCK_HAY_BALE: return new cBlockSidewaysHandler (a_BlockType);
|
case E_BLOCK_HAY_BALE: return new cBlockSidewaysHandler (a_BlockType);
|
||||||
|
case E_BLOCK_HEAD: return new cBlockMobHeadHandler (a_BlockType);
|
||||||
case E_BLOCK_HOPPER: return new cBlockHopperHandler (a_BlockType);
|
case E_BLOCK_HOPPER: return new cBlockHopperHandler (a_BlockType);
|
||||||
case E_BLOCK_ICE: return new cBlockIceHandler (a_BlockType);
|
case E_BLOCK_ICE: return new cBlockIceHandler (a_BlockType);
|
||||||
case E_BLOCK_INACTIVE_COMPARATOR: return new cBlockComparatorHandler (a_BlockType);
|
case E_BLOCK_INACTIVE_COMPARATOR: return new cBlockComparatorHandler (a_BlockType);
|
||||||
|
69
src/Blocks/BlockMobHead.h
Normal file
69
src/Blocks/BlockMobHead.h
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "BlockEntity.h"
|
||||||
|
#include "../BlockEntities/MobHeadEntity.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class cBlockMobHeadHandler :
|
||||||
|
public cBlockEntityHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
cBlockMobHeadHandler(BLOCKTYPE a_BlockType)
|
||||||
|
: cBlockEntityHandler(a_BlockType)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
||||||
|
{
|
||||||
|
a_Pickups.push_back(cItem(E_ITEM_HEAD, 1, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void OnPlacedByPlayer(
|
||||||
|
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player,
|
||||||
|
int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
|
||||||
|
int a_CursorX, int a_CursorY, int a_CursorZ,
|
||||||
|
BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta
|
||||||
|
) override
|
||||||
|
{
|
||||||
|
class cCallback : public cMobHeadBlockCallback
|
||||||
|
{
|
||||||
|
cPlayer * m_Player;
|
||||||
|
NIBBLETYPE m_OldBlockMeta;
|
||||||
|
NIBBLETYPE m_NewBlockMeta;
|
||||||
|
|
||||||
|
virtual bool Item (cMobHeadEntity * a_MobHeadEntity)
|
||||||
|
{
|
||||||
|
int Rotation = 0;
|
||||||
|
if (m_NewBlockMeta == 1)
|
||||||
|
{
|
||||||
|
Rotation = (int) floor(m_Player->GetYaw() * 16.0F / 360.0F + 0.5) & 0xF;
|
||||||
|
}
|
||||||
|
|
||||||
|
a_MobHeadEntity->SetType(static_cast<eMobHeadType>(m_OldBlockMeta));
|
||||||
|
a_MobHeadEntity->SetRotation(static_cast<eMobHeadRotation>(Rotation));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
cCallback (cPlayer * a_Player, NIBBLETYPE a_OldBlockMeta, NIBBLETYPE a_NewBlockMeta) :
|
||||||
|
m_Player(a_Player),
|
||||||
|
m_OldBlockMeta(a_OldBlockMeta),
|
||||||
|
m_NewBlockMeta(a_NewBlockMeta)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
cCallback Callback(a_Player, a_BlockMeta, static_cast<NIBBLETYPE>(a_BlockFace));
|
||||||
|
|
||||||
|
a_BlockMeta = a_BlockFace;
|
||||||
|
cWorld * World = (cWorld *) &a_WorldInterface;
|
||||||
|
World->DoWithMobHeadBlockAt(a_BlockX, a_BlockY, a_BlockZ, Callback);
|
||||||
|
a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, a_BlockMeta);
|
||||||
|
}
|
||||||
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -39,6 +39,7 @@ if (NOT MSVC)
|
|||||||
BlockEntities/JukeboxEntity.h
|
BlockEntities/JukeboxEntity.h
|
||||||
BlockEntities/NoteEntity.h
|
BlockEntities/NoteEntity.h
|
||||||
BlockEntities/SignEntity.h
|
BlockEntities/SignEntity.h
|
||||||
|
BlockEntities/MobHeadEntity.h
|
||||||
BlockID.h
|
BlockID.h
|
||||||
BoundingBox.h
|
BoundingBox.h
|
||||||
ChatColor.h
|
ChatColor.h
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "BlockEntities/JukeboxEntity.h"
|
#include "BlockEntities/JukeboxEntity.h"
|
||||||
#include "BlockEntities/NoteEntity.h"
|
#include "BlockEntities/NoteEntity.h"
|
||||||
#include "BlockEntities/SignEntity.h"
|
#include "BlockEntities/SignEntity.h"
|
||||||
|
#include "BlockEntities/MobHeadEntity.h"
|
||||||
#include "Entities/Pickup.h"
|
#include "Entities/Pickup.h"
|
||||||
#include "Item.h"
|
#include "Item.h"
|
||||||
#include "Noise.h"
|
#include "Noise.h"
|
||||||
@ -1314,6 +1315,7 @@ void cChunk::CreateBlockEntities(void)
|
|||||||
case E_BLOCK_HOPPER:
|
case E_BLOCK_HOPPER:
|
||||||
case E_BLOCK_SIGN_POST:
|
case E_BLOCK_SIGN_POST:
|
||||||
case E_BLOCK_WALLSIGN:
|
case E_BLOCK_WALLSIGN:
|
||||||
|
case E_BLOCK_HEAD:
|
||||||
case E_BLOCK_NOTE_BLOCK:
|
case E_BLOCK_NOTE_BLOCK:
|
||||||
case E_BLOCK_JUKEBOX:
|
case E_BLOCK_JUKEBOX:
|
||||||
{
|
{
|
||||||
@ -1442,6 +1444,7 @@ void cChunk::SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType,
|
|||||||
case E_BLOCK_HOPPER:
|
case E_BLOCK_HOPPER:
|
||||||
case E_BLOCK_SIGN_POST:
|
case E_BLOCK_SIGN_POST:
|
||||||
case E_BLOCK_WALLSIGN:
|
case E_BLOCK_WALLSIGN:
|
||||||
|
case E_BLOCK_HEAD:
|
||||||
case E_BLOCK_NOTE_BLOCK:
|
case E_BLOCK_NOTE_BLOCK:
|
||||||
case E_BLOCK_JUKEBOX:
|
case E_BLOCK_JUKEBOX:
|
||||||
{
|
{
|
||||||
@ -2341,6 +2344,38 @@ bool cChunk::DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cCom
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cChunk::DoWithMobHeadBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadBlockCallback & a_Callback)
|
||||||
|
{
|
||||||
|
// The blockentity list is locked by the parent chunkmap's CS
|
||||||
|
for (cBlockEntityList::iterator itr = m_BlockEntities.begin(), itr2 = itr; itr != m_BlockEntities.end(); itr = itr2)
|
||||||
|
{
|
||||||
|
++itr2;
|
||||||
|
if (((*itr)->GetPosX() != a_BlockX) || ((*itr)->GetPosY() != a_BlockY) || ((*itr)->GetPosZ() != a_BlockZ))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ((*itr)->GetBlockType() != E_BLOCK_HEAD)
|
||||||
|
{
|
||||||
|
// There is a block entity here, but of different type. No other block entity can be here, so we can safely bail out
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The correct block entity is here,
|
||||||
|
if (a_Callback.Item((cMobHeadEntity *)*itr))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} // for itr - m_BlockEntitites[]
|
||||||
|
|
||||||
|
// Not found:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunk::GetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4)
|
bool cChunk::GetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4)
|
||||||
{
|
{
|
||||||
// The blockentity list is locked by the parent chunkmap's CS
|
// The blockentity list is locked by the parent chunkmap's CS
|
||||||
|
@ -31,6 +31,7 @@ class cChestEntity;
|
|||||||
class cDispenserEntity;
|
class cDispenserEntity;
|
||||||
class cFurnaceEntity;
|
class cFurnaceEntity;
|
||||||
class cNoteEntity;
|
class cNoteEntity;
|
||||||
|
class cMobHeadEntity;
|
||||||
class cBlockArea;
|
class cBlockArea;
|
||||||
class cPawn;
|
class cPawn;
|
||||||
class cPickup;
|
class cPickup;
|
||||||
@ -47,6 +48,7 @@ typedef cItemCallback<cDispenserEntity> cDispenserCallback;
|
|||||||
typedef cItemCallback<cFurnaceEntity> cFurnaceCallback;
|
typedef cItemCallback<cFurnaceEntity> cFurnaceCallback;
|
||||||
typedef cItemCallback<cNoteEntity> cNoteBlockCallback;
|
typedef cItemCallback<cNoteEntity> cNoteBlockCallback;
|
||||||
typedef cItemCallback<cCommandBlockEntity> cCommandBlockCallback;
|
typedef cItemCallback<cCommandBlockEntity> cCommandBlockCallback;
|
||||||
|
typedef cItemCallback<cMobHeadEntity> cMobHeadBlockCallback;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -249,7 +251,10 @@ public:
|
|||||||
bool DoWithNoteBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cNoteBlockCallback & a_Callback);
|
bool DoWithNoteBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cNoteBlockCallback & a_Callback);
|
||||||
|
|
||||||
/** Calls the callback for the command block at the specified coords; returns false if there's no command block at those coords or callback returns true, returns true if found */
|
/** Calls the callback for the command block at the specified coords; returns false if there's no command block at those coords or callback returns true, returns true if found */
|
||||||
bool DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cCommandBlockCallback & a_Callback);
|
bool DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cCommandBlockCallback & a_Callback);
|
||||||
|
|
||||||
|
/** Calls the callback for the mob head block at the specified coords; returns false if there's no mob header block at those coords or callback returns true, returns true if found */
|
||||||
|
bool DoWithMobHeadBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadBlockCallback & a_Callback);
|
||||||
|
|
||||||
/** Retrieves the test on the sign at the specified coords; returns false if there's no sign at those coords, true if found */
|
/** Retrieves the test on the sign at the specified coords; returns false if there's no sign at those coords, true if found */
|
||||||
bool GetSignLines (int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4); // Lua-accessible
|
bool GetSignLines (int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4); // Lua-accessible
|
||||||
|
@ -2178,6 +2178,24 @@ bool cChunkMap::DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, c
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cChunkMap::DoWithMobHeadBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadBlockCallback & a_Callback)
|
||||||
|
{
|
||||||
|
int ChunkX, ChunkZ;
|
||||||
|
int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ;
|
||||||
|
cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ);
|
||||||
|
cCSLock Lock(m_CSLayers);
|
||||||
|
cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ);
|
||||||
|
if ((Chunk == NULL) && !Chunk->IsValid())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return Chunk->DoWithMobHeadBlockAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunkMap::GetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4)
|
bool cChunkMap::GetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4)
|
||||||
{
|
{
|
||||||
int ChunkX, ChunkZ;
|
int ChunkX, ChunkZ;
|
||||||
|
@ -25,6 +25,7 @@ class cDropSpenserEntity;
|
|||||||
class cFurnaceEntity;
|
class cFurnaceEntity;
|
||||||
class cNoteEntity;
|
class cNoteEntity;
|
||||||
class cCommandBlockEntity;
|
class cCommandBlockEntity;
|
||||||
|
class cMobHeadEntity;
|
||||||
class cPawn;
|
class cPawn;
|
||||||
class cPickup;
|
class cPickup;
|
||||||
class cChunkDataSerializer;
|
class cChunkDataSerializer;
|
||||||
@ -43,6 +44,7 @@ typedef cItemCallback<cDropSpenserEntity> cDropSpenserCallback;
|
|||||||
typedef cItemCallback<cFurnaceEntity> cFurnaceCallback;
|
typedef cItemCallback<cFurnaceEntity> cFurnaceCallback;
|
||||||
typedef cItemCallback<cNoteEntity> cNoteBlockCallback;
|
typedef cItemCallback<cNoteEntity> cNoteBlockCallback;
|
||||||
typedef cItemCallback<cCommandBlockEntity> cCommandBlockCallback;
|
typedef cItemCallback<cCommandBlockEntity> cCommandBlockCallback;
|
||||||
|
typedef cItemCallback<cMobHeadEntity> cMobHeadBlockCallback;
|
||||||
typedef cItemCallback<cChunk> cChunkCallback;
|
typedef cItemCallback<cChunk> cChunkCallback;
|
||||||
|
|
||||||
|
|
||||||
@ -254,6 +256,9 @@ public:
|
|||||||
/** Calls the callback for the command block at the specified coords; returns false if there's no command block at those coords or callback returns true, returns true if found */
|
/** Calls the callback for the command block at the specified coords; returns false if there's no command block at those coords or callback returns true, returns true if found */
|
||||||
bool DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cCommandBlockCallback & a_Callback); // Lua-accessible
|
bool DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cCommandBlockCallback & a_Callback); // Lua-accessible
|
||||||
|
|
||||||
|
/** Calls the callback for the mob head block at the specified coords; returns false if there's no mob head block at those coords or callback returns true, returns true if found */
|
||||||
|
bool DoWithMobHeadBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadBlockCallback & a_Callback); // Lua-accessible
|
||||||
|
|
||||||
/** Retrieves the test on the sign at the specified coords; returns false if there's no sign at those coords, true if found */
|
/** Retrieves the test on the sign at the specified coords; returns false if there's no sign at those coords, true if found */
|
||||||
bool GetSignLines (int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4); // Lua-accessible
|
bool GetSignLines (int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4); // Lua-accessible
|
||||||
|
|
||||||
|
@ -174,6 +174,43 @@ enum eWeather
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
enum eMobHeadType
|
||||||
|
{
|
||||||
|
SKULL_TYPE_SKELETON = 0,
|
||||||
|
SKULL_TYPE_WITHER = 1,
|
||||||
|
SKULL_TYPE_ZOMBIE = 2,
|
||||||
|
SKULL_TYPE_PLAYER = 3,
|
||||||
|
SKULL_TYPE_CREEPER = 4,
|
||||||
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
enum eMobHeadRotation
|
||||||
|
{
|
||||||
|
SKULL_ROTATION_NORTH = 0,
|
||||||
|
SKULL_ROTATION_NORTH_NORTH_EAST = 1,
|
||||||
|
SKULL_ROTATION_NORTH_EAST = 2,
|
||||||
|
SKULL_ROTATION_EAST_NORTH_EAST = 3,
|
||||||
|
SKULL_ROTATION_EAST = 4,
|
||||||
|
SKULL_ROTATION_EAST_SOUTH_EAST = 5,
|
||||||
|
SKULL_ROTATION_SOUTH_EAST = 6,
|
||||||
|
SKULL_ROTATION_SOUTH_SOUTH_EAST = 7,
|
||||||
|
SKULL_ROTATION_SOUTH = 8,
|
||||||
|
SKULL_ROTATION_SOUTH_SOUTH_WEST = 9,
|
||||||
|
SKULL_ROTATION_SOUTH_WEST = 10,
|
||||||
|
SKULL_ROTATION_WEST_SOUTH_WEST = 11,
|
||||||
|
SKULL_ROTATION_WEST = 12,
|
||||||
|
SKULL_ROTATION_WEST_NORTH_WEST = 13,
|
||||||
|
SKULL_ROTATION_NORTH_WEST = 14,
|
||||||
|
SKULL_ROTATION_NORTH_NORTH_WEST = 15,
|
||||||
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
inline const char * ClickActionToString(eClickAction a_ClickAction)
|
inline const char * ClickActionToString(eClickAction a_ClickAction)
|
||||||
{
|
{
|
||||||
switch (a_ClickAction)
|
switch (a_ClickAction)
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include "ItemShears.h"
|
#include "ItemShears.h"
|
||||||
#include "ItemShovel.h"
|
#include "ItemShovel.h"
|
||||||
#include "ItemSign.h"
|
#include "ItemSign.h"
|
||||||
|
#include "ItemMobHead.h"
|
||||||
#include "ItemSpawnEgg.h"
|
#include "ItemSpawnEgg.h"
|
||||||
#include "ItemSugarcane.h"
|
#include "ItemSugarcane.h"
|
||||||
#include "ItemSword.h"
|
#include "ItemSword.h"
|
||||||
@ -114,6 +115,7 @@ cItemHandler *cItemHandler::CreateItemHandler(int a_ItemType)
|
|||||||
case E_ITEM_REDSTONE_REPEATER: return new cItemRedstoneRepeaterHandler(a_ItemType);
|
case E_ITEM_REDSTONE_REPEATER: return new cItemRedstoneRepeaterHandler(a_ItemType);
|
||||||
case E_ITEM_SHEARS: return new cItemShearsHandler(a_ItemType);
|
case E_ITEM_SHEARS: return new cItemShearsHandler(a_ItemType);
|
||||||
case E_ITEM_SIGN: return new cItemSignHandler(a_ItemType);
|
case E_ITEM_SIGN: return new cItemSignHandler(a_ItemType);
|
||||||
|
case E_ITEM_HEAD: return new cItemMobHeadHandler(a_ItemType);
|
||||||
case E_ITEM_SNOWBALL: return new cItemSnowballHandler();
|
case E_ITEM_SNOWBALL: return new cItemSnowballHandler();
|
||||||
case E_ITEM_SPAWN_EGG: return new cItemSpawnEggHandler(a_ItemType);
|
case E_ITEM_SPAWN_EGG: return new cItemSpawnEggHandler(a_ItemType);
|
||||||
case E_ITEM_SUGARCANE: return new cItemSugarcaneHandler(a_ItemType);
|
case E_ITEM_SUGARCANE: return new cItemSugarcaneHandler(a_ItemType);
|
||||||
|
42
src/Items/ItemMobHead.h
Normal file
42
src/Items/ItemMobHead.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ItemHandler.h"
|
||||||
|
#include "../World.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class cItemMobHeadHandler :
|
||||||
|
public cItemHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
cItemMobHeadHandler(int a_ItemType) :
|
||||||
|
cItemHandler(a_ItemType)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual bool IsPlaceable(void) override
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual bool GetPlacementBlockTypeMeta(
|
||||||
|
cWorld * a_World, cPlayer * a_Player,
|
||||||
|
int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
|
||||||
|
int a_CursorX, int a_CursorY, int a_CursorZ,
|
||||||
|
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
|
||||||
|
) override
|
||||||
|
{
|
||||||
|
a_BlockType = E_BLOCK_HEAD;
|
||||||
|
a_BlockMeta = (NIBBLETYPE)(a_Player->GetEquippedItem().m_ItemDamage & 0x0f);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -28,6 +28,7 @@ Implements the 1.7.x protocol classes:
|
|||||||
#include "../Mobs/IncludeAllMonsters.h"
|
#include "../Mobs/IncludeAllMonsters.h"
|
||||||
#include "../UI/Window.h"
|
#include "../UI/Window.h"
|
||||||
#include "../BlockEntities/CommandBlockEntity.h"
|
#include "../BlockEntities/CommandBlockEntity.h"
|
||||||
|
#include "../BlockEntities/MobHeadEntity.h"
|
||||||
#include "../CompositeChat.h"
|
#include "../CompositeChat.h"
|
||||||
|
|
||||||
|
|
||||||
@ -1058,6 +1059,7 @@ void cProtocol172::SendUpdateBlockEntity(cBlockEntity & a_BlockEntity)
|
|||||||
{
|
{
|
||||||
case E_BLOCK_MOB_SPAWNER: Action = 1; break; // Update mob spawner spinny mob thing
|
case E_BLOCK_MOB_SPAWNER: Action = 1; break; // Update mob spawner spinny mob thing
|
||||||
case E_BLOCK_COMMAND_BLOCK: Action = 2; break; // Update command block text
|
case E_BLOCK_COMMAND_BLOCK: Action = 2; break; // Update command block text
|
||||||
|
case E_BLOCK_HEAD: Action = 4; break; // Update Mobhead entity
|
||||||
default: ASSERT(!"Unhandled or unimplemented BlockEntity update request!"); break;
|
default: ASSERT(!"Unhandled or unimplemented BlockEntity update request!"); break;
|
||||||
}
|
}
|
||||||
Pkt.WriteByte(Action);
|
Pkt.WriteByte(Action);
|
||||||
@ -2285,6 +2287,19 @@ void cProtocol172::cPacketizer::WriteBlockEntity(const cBlockEntity & a_BlockEnt
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case E_BLOCK_HEAD:
|
||||||
|
{
|
||||||
|
cMobHeadEntity & MobHeadEntity = (cMobHeadEntity &)a_BlockEntity;
|
||||||
|
|
||||||
|
Writer.AddInt("x", MobHeadEntity.GetPosX());
|
||||||
|
Writer.AddInt("y", MobHeadEntity.GetPosY());
|
||||||
|
Writer.AddInt("z", MobHeadEntity.GetPosZ());
|
||||||
|
Writer.AddByte("SkullType", MobHeadEntity.GetType() & 0xFF);
|
||||||
|
Writer.AddByte("Rot", MobHeadEntity.GetRotation() & 0xFF);
|
||||||
|
Writer.AddString("ExtraType", MobHeadEntity.GetOwner().c_str());
|
||||||
|
Writer.AddString("id", "Skull"); // "Tile Entity ID" - MC wiki; vanilla server always seems to send this though
|
||||||
|
break;
|
||||||
|
}
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1165,6 +1165,15 @@ bool cWorld::DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cCom
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cWorld::DoWithMobHeadBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadBlockCallback & a_Callback)
|
||||||
|
{
|
||||||
|
return m_ChunkMap->DoWithMobHeadBlockAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cWorld::GetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4)
|
bool cWorld::GetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4)
|
||||||
{
|
{
|
||||||
return m_ChunkMap->GetSignLines(a_BlockX, a_BlockY, a_BlockZ, a_Line1, a_Line2, a_Line3, a_Line4);
|
return m_ChunkMap->GetSignLines(a_BlockX, a_BlockY, a_BlockZ, a_Line1, a_Line2, a_Line3, a_Line4);
|
||||||
|
@ -45,6 +45,7 @@ class cChestEntity;
|
|||||||
class cDispenserEntity;
|
class cDispenserEntity;
|
||||||
class cFurnaceEntity;
|
class cFurnaceEntity;
|
||||||
class cNoteEntity;
|
class cNoteEntity;
|
||||||
|
class cMobHeadEntity;
|
||||||
class cMobCensus;
|
class cMobCensus;
|
||||||
class cCompositeChat;
|
class cCompositeChat;
|
||||||
class cCuboid;
|
class cCuboid;
|
||||||
@ -58,6 +59,7 @@ typedef cItemCallback<cDispenserEntity> cDispenserCallback;
|
|||||||
typedef cItemCallback<cFurnaceEntity> cFurnaceCallback;
|
typedef cItemCallback<cFurnaceEntity> cFurnaceCallback;
|
||||||
typedef cItemCallback<cNoteEntity> cNoteBlockCallback;
|
typedef cItemCallback<cNoteEntity> cNoteBlockCallback;
|
||||||
typedef cItemCallback<cCommandBlockEntity> cCommandBlockCallback;
|
typedef cItemCallback<cCommandBlockEntity> cCommandBlockCallback;
|
||||||
|
typedef cItemCallback<cMobHeadEntity> cMobHeadBlockCallback;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -519,6 +521,9 @@ public:
|
|||||||
/** Calls the callback for the command block at the specified coords; returns false if there's no command block at those coords or callback returns true, returns true if found */
|
/** Calls the callback for the command block at the specified coords; returns false if there's no command block at those coords or callback returns true, returns true if found */
|
||||||
bool DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cCommandBlockCallback & a_Callback); // Exported in ManualBindings.cpp
|
bool DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cCommandBlockCallback & a_Callback); // Exported in ManualBindings.cpp
|
||||||
|
|
||||||
|
/** Calls the callback for the mob head block at the specified coords; returns false if there's no mob head block at those coords or callback returns true, returns true if found */
|
||||||
|
bool DoWithMobHeadBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadBlockCallback & a_Callback); // Exported in ManualBindings.cpp
|
||||||
|
|
||||||
/** Retrieves the test on the sign at the specified coords; returns false if there's no sign at those coords, true if found */
|
/** Retrieves the test on the sign at the specified coords; returns false if there's no sign at those coords, true if found */
|
||||||
bool GetSignLines (int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4); // Exported in ManualBindings.cpp
|
bool GetSignLines (int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4); // Exported in ManualBindings.cpp
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "../BlockEntities/JukeboxEntity.h"
|
#include "../BlockEntities/JukeboxEntity.h"
|
||||||
#include "../BlockEntities/NoteEntity.h"
|
#include "../BlockEntities/NoteEntity.h"
|
||||||
#include "../BlockEntities/SignEntity.h"
|
#include "../BlockEntities/SignEntity.h"
|
||||||
|
#include "../BlockEntities/MobHeadEntity.h"
|
||||||
|
|
||||||
#include "../Entities/Entity.h"
|
#include "../Entities/Entity.h"
|
||||||
#include "../Entities/FallingBlock.h"
|
#include "../Entities/FallingBlock.h"
|
||||||
@ -248,11 +249,25 @@ void cNBTChunkSerializer::AddCommandBlockEntity(cCommandBlockEntity * a_CmdBlock
|
|||||||
void cNBTChunkSerializer::AddSignEntity(cSignEntity * a_Sign)
|
void cNBTChunkSerializer::AddSignEntity(cSignEntity * a_Sign)
|
||||||
{
|
{
|
||||||
m_Writer.BeginCompound("");
|
m_Writer.BeginCompound("");
|
||||||
AddBasicTileEntity(a_Sign, "Sign");
|
AddBasicTileEntity(a_Sign, "Sign");
|
||||||
m_Writer.AddString("Text1", a_Sign->GetLine(0));
|
m_Writer.AddString("Text1", a_Sign->GetLine(0));
|
||||||
m_Writer.AddString("Text2", a_Sign->GetLine(1));
|
m_Writer.AddString("Text2", a_Sign->GetLine(1));
|
||||||
m_Writer.AddString("Text3", a_Sign->GetLine(2));
|
m_Writer.AddString("Text3", a_Sign->GetLine(2));
|
||||||
m_Writer.AddString("Text4", a_Sign->GetLine(3));
|
m_Writer.AddString("Text4", a_Sign->GetLine(3));
|
||||||
|
m_Writer.EndCompound();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cNBTChunkSerializer::AddMobHeadEntity(cMobHeadEntity * a_MobHead)
|
||||||
|
{
|
||||||
|
m_Writer.BeginCompound("");
|
||||||
|
AddBasicTileEntity(a_MobHead, "Skull");
|
||||||
|
m_Writer.AddByte ("SkullType", a_MobHead->GetType() & 0xFF);
|
||||||
|
m_Writer.AddByte ("Rot", a_MobHead->GetRotation() & 0xFF);
|
||||||
|
m_Writer.AddString("ExtraType", a_MobHead->GetOwner());
|
||||||
m_Writer.EndCompound();
|
m_Writer.EndCompound();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -668,6 +683,7 @@ void cNBTChunkSerializer::BlockEntity(cBlockEntity * a_Entity)
|
|||||||
case E_BLOCK_HOPPER: AddHopperEntity ((cHopperEntity *) a_Entity); break;
|
case E_BLOCK_HOPPER: AddHopperEntity ((cHopperEntity *) a_Entity); break;
|
||||||
case E_BLOCK_SIGN_POST:
|
case E_BLOCK_SIGN_POST:
|
||||||
case E_BLOCK_WALLSIGN: AddSignEntity ((cSignEntity *) a_Entity); break;
|
case E_BLOCK_WALLSIGN: AddSignEntity ((cSignEntity *) a_Entity); break;
|
||||||
|
case E_BLOCK_HEAD: AddMobHeadEntity ((cMobHeadEntity *) a_Entity); break;
|
||||||
case E_BLOCK_NOTE_BLOCK: AddNoteEntity ((cNoteEntity *) a_Entity); break;
|
case E_BLOCK_NOTE_BLOCK: AddNoteEntity ((cNoteEntity *) a_Entity); break;
|
||||||
case E_BLOCK_JUKEBOX: AddJukeboxEntity ((cJukeboxEntity *) a_Entity); break;
|
case E_BLOCK_JUKEBOX: AddJukeboxEntity ((cJukeboxEntity *) a_Entity); break;
|
||||||
case E_BLOCK_COMMAND_BLOCK: AddCommandBlockEntity((cCommandBlockEntity *) a_Entity); break;
|
case E_BLOCK_COMMAND_BLOCK: AddCommandBlockEntity((cCommandBlockEntity *) a_Entity); break;
|
||||||
|
@ -29,6 +29,7 @@ class cHopperEntity;
|
|||||||
class cJukeboxEntity;
|
class cJukeboxEntity;
|
||||||
class cNoteEntity;
|
class cNoteEntity;
|
||||||
class cSignEntity;
|
class cSignEntity;
|
||||||
|
class cMobHeadEntity;
|
||||||
class cFallingBlock;
|
class cFallingBlock;
|
||||||
class cMinecart;
|
class cMinecart;
|
||||||
class cMinecartWithChest;
|
class cMinecartWithChest;
|
||||||
@ -93,6 +94,7 @@ protected:
|
|||||||
void AddJukeboxEntity (cJukeboxEntity * a_Jukebox);
|
void AddJukeboxEntity (cJukeboxEntity * a_Jukebox);
|
||||||
void AddNoteEntity (cNoteEntity * a_Note);
|
void AddNoteEntity (cNoteEntity * a_Note);
|
||||||
void AddSignEntity (cSignEntity * a_Sign);
|
void AddSignEntity (cSignEntity * a_Sign);
|
||||||
|
void AddMobHeadEntity (cMobHeadEntity * a_MobHead);
|
||||||
void AddCommandBlockEntity(cCommandBlockEntity * a_CmdBlock);
|
void AddCommandBlockEntity(cCommandBlockEntity * a_CmdBlock);
|
||||||
|
|
||||||
// Entities:
|
// Entities:
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "../BlockEntities/JukeboxEntity.h"
|
#include "../BlockEntities/JukeboxEntity.h"
|
||||||
#include "../BlockEntities/NoteEntity.h"
|
#include "../BlockEntities/NoteEntity.h"
|
||||||
#include "../BlockEntities/SignEntity.h"
|
#include "../BlockEntities/SignEntity.h"
|
||||||
|
#include "../BlockEntities/MobHeadEntity.h"
|
||||||
|
|
||||||
|
|
||||||
#include "../Mobs/Monster.h"
|
#include "../Mobs/Monster.h"
|
||||||
@ -597,6 +598,10 @@ void cWSSAnvil::LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntities, con
|
|||||||
{
|
{
|
||||||
LoadSignFromNBT(a_BlockEntities, a_NBT, Child);
|
LoadSignFromNBT(a_BlockEntities, a_NBT, Child);
|
||||||
}
|
}
|
||||||
|
else if (strncmp(a_NBT.GetData(sID), "Skull", a_NBT.GetDataLength(sID)) == 0)
|
||||||
|
{
|
||||||
|
LoadMobHeadFromNBT(a_BlockEntities, a_NBT, Child);
|
||||||
|
}
|
||||||
else if (strncmp(a_NBT.GetData(sID), "Trap", a_NBT.GetDataLength(sID)) == 0)
|
else if (strncmp(a_NBT.GetData(sID), "Trap", a_NBT.GetDataLength(sID)) == 0)
|
||||||
{
|
{
|
||||||
LoadDispenserFromNBT(a_BlockEntities, a_NBT, Child);
|
LoadDispenserFromNBT(a_BlockEntities, a_NBT, Child);
|
||||||
@ -927,6 +932,41 @@ void cWSSAnvil::LoadSignFromNBT(cBlockEntityList & a_BlockEntities, const cParse
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cWSSAnvil::LoadMobHeadFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx)
|
||||||
|
{
|
||||||
|
ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound);
|
||||||
|
int x, y, z;
|
||||||
|
if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::auto_ptr<cMobHeadEntity> MobHead(new cMobHeadEntity(x, y, z, m_World));
|
||||||
|
|
||||||
|
int currentLine = a_NBT.FindChildByName(a_TagIdx, "SkullType");
|
||||||
|
if (currentLine >= 0)
|
||||||
|
{
|
||||||
|
MobHead->SetType(static_cast<eMobHeadType>(a_NBT.GetByte(currentLine)));
|
||||||
|
}
|
||||||
|
|
||||||
|
currentLine = a_NBT.FindChildByName(a_TagIdx, "Rot");
|
||||||
|
if (currentLine >= 0)
|
||||||
|
{
|
||||||
|
MobHead->SetRotation(static_cast<eMobHeadRotation>(a_NBT.GetByte(currentLine)));
|
||||||
|
}
|
||||||
|
|
||||||
|
currentLine = a_NBT.FindChildByName(a_TagIdx, "ExtraType");
|
||||||
|
if (currentLine >= 0)
|
||||||
|
{
|
||||||
|
MobHead->SetOwner(a_NBT.GetString(currentLine));
|
||||||
|
}
|
||||||
|
|
||||||
|
a_BlockEntities.push_back(MobHead.release());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cWSSAnvil::LoadCommandBlockFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx)
|
void cWSSAnvil::LoadCommandBlockFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx)
|
||||||
{
|
{
|
||||||
ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound);
|
ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound);
|
||||||
|
@ -139,6 +139,7 @@ protected:
|
|||||||
void LoadJukeboxFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
|
void LoadJukeboxFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||||
void LoadNoteFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
|
void LoadNoteFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||||
void LoadSignFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
|
void LoadSignFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||||
|
void LoadMobHeadFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||||
void LoadCommandBlockFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
|
void LoadCommandBlockFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||||
|
|
||||||
void LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_EntityTagIdx, const char * a_IDTag, int a_IDTagLength);
|
void LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_EntityTagIdx, const char * a_IDTag, int a_IDTagLength);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user