1
0

Merge pull request #557 from xdot/master

Command blocks
This commit is contained in:
Mattes D 2014-01-18 11:39:42 -08:00
commit 36b9d42819
20 changed files with 593 additions and 62 deletions

View File

@ -20,5 +20,6 @@ worktycho
Sxw1212 Sxw1212
tonibm19 tonibm19
Diusrex Diusrex
structinf (xdot)
Please add yourself to this list if you contribute to MCServer. Please add yourself to this list if you contribute to MCServer.

View File

@ -14,6 +14,7 @@
#include "../WebAdmin.h" #include "../WebAdmin.h"
#include "../ClientHandle.h" #include "../ClientHandle.h"
#include "../BlockEntities/ChestEntity.h" #include "../BlockEntities/ChestEntity.h"
#include "../BlockEntities/CommandBlockEntity.h"
#include "../BlockEntities/DispenserEntity.h" #include "../BlockEntities/DispenserEntity.h"
#include "../BlockEntities/DropperEntity.h" #include "../BlockEntities/DropperEntity.h"
#include "../BlockEntities/FurnaceEntity.h" #include "../BlockEntities/FurnaceEntity.h"
@ -2265,16 +2266,17 @@ void ManualBindings::Bind(lua_State * tolua_S)
tolua_endmodule(tolua_S); tolua_endmodule(tolua_S);
tolua_beginmodule(tolua_S, "cWorld"); tolua_beginmodule(tolua_S, "cWorld");
tolua_function(tolua_S, "DoWithBlockEntityAt", tolua_DoWithXYZ<cWorld, cBlockEntity, &cWorld::DoWithBlockEntityAt>); tolua_function(tolua_S, "DoWithBlockEntityAt", tolua_DoWithXYZ<cWorld, cBlockEntity, &cWorld::DoWithBlockEntityAt>);
tolua_function(tolua_S, "DoWithChestAt", tolua_DoWithXYZ<cWorld, cChestEntity, &cWorld::DoWithChestAt>); tolua_function(tolua_S, "DoWithChestAt", tolua_DoWithXYZ<cWorld, cChestEntity, &cWorld::DoWithChestAt>);
tolua_function(tolua_S, "DoWithDispenserAt", tolua_DoWithXYZ<cWorld, cDispenserEntity, &cWorld::DoWithDispenserAt>); tolua_function(tolua_S, "DoWithDispenserAt", tolua_DoWithXYZ<cWorld, cDispenserEntity, &cWorld::DoWithDispenserAt>);
tolua_function(tolua_S, "DoWithDropSpenserAt", tolua_DoWithXYZ<cWorld, cDropSpenserEntity, &cWorld::DoWithDropSpenserAt>); tolua_function(tolua_S, "DoWithDropSpenserAt", tolua_DoWithXYZ<cWorld, cDropSpenserEntity, &cWorld::DoWithDropSpenserAt>);
tolua_function(tolua_S, "DoWithDropperAt", tolua_DoWithXYZ<cWorld, cDropperEntity, &cWorld::DoWithDropperAt>); tolua_function(tolua_S, "DoWithDropperAt", tolua_DoWithXYZ<cWorld, cDropperEntity, &cWorld::DoWithDropperAt>);
tolua_function(tolua_S, "DoWithEntityByID", tolua_DoWithID< cWorld, cEntity, &cWorld::DoWithEntityByID>); tolua_function(tolua_S, "DoWithEntityByID", tolua_DoWithID< cWorld, cEntity, &cWorld::DoWithEntityByID>);
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, "DoWithPlayer", tolua_DoWith< cWorld, cPlayer, &cWorld::DoWithPlayer>); tolua_function(tolua_S, "DoWithCommandBlockAt", tolua_DoWithXYZ<cWorld, cCommandBlockEntity, &cWorld::DoWithCommandBlockAt>);
tolua_function(tolua_S, "FindAndDoWithPlayer", tolua_DoWith< cWorld, cPlayer, &cWorld::FindAndDoWithPlayer>); 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, "ForEachBlockEntityInChunk", tolua_ForEachInChunk<cWorld, cBlockEntity, &cWorld::ForEachBlockEntityInChunk>); tolua_function(tolua_S, "ForEachBlockEntityInChunk", tolua_ForEachInChunk<cWorld, cBlockEntity, &cWorld::ForEachBlockEntityInChunk>);
tolua_function(tolua_S, "ForEachChestInChunk", tolua_ForEachInChunk<cWorld, cChestEntity, &cWorld::ForEachChestInChunk>); tolua_function(tolua_S, "ForEachChestInChunk", tolua_ForEachInChunk<cWorld, cChestEntity, &cWorld::ForEachChestInChunk>);
tolua_function(tolua_S, "ForEachEntity", tolua_ForEach< cWorld, cEntity, &cWorld::ForEachEntity>); tolua_function(tolua_S, "ForEachEntity", tolua_ForEach< cWorld, cEntity, &cWorld::ForEachEntity>);

View File

@ -6,6 +6,7 @@
#include "Globals.h" #include "Globals.h"
#include "BlockEntity.h" #include "BlockEntity.h"
#include "ChestEntity.h" #include "ChestEntity.h"
#include "CommandBlockEntity.h"
#include "DispenserEntity.h" #include "DispenserEntity.h"
#include "DropperEntity.h" #include "DropperEntity.h"
#include "EnderChestEntity.h" #include "EnderChestEntity.h"
@ -23,17 +24,18 @@ cBlockEntity * cBlockEntity::CreateByBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE
{ {
switch (a_BlockType) switch (a_BlockType)
{ {
case E_BLOCK_CHEST: return new cChestEntity (a_BlockX, a_BlockY, a_BlockZ, a_World); case E_BLOCK_CHEST: return new cChestEntity (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_COMMAND_BLOCK: return new cCommandBlockEntity(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_DISPENSER: return new cDispenserEntity (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_DROPPER: return new cDropperEntity (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_ENDER_CHEST: return new cEnderChestEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
case E_BLOCK_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_HOPPER: return new cHopperEntity (a_BlockX, a_BlockY, a_BlockZ, a_World); case E_BLOCK_FURNACE: return new cFurnaceEntity (a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_World);
case E_BLOCK_SIGN_POST: return new cSignEntity (a_BlockType, a_BlockX, a_BlockY, a_BlockZ, a_World); case E_BLOCK_HOPPER: return new cHopperEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
case E_BLOCK_WALLSIGN: return new cSignEntity (a_BlockType, a_BlockX, a_BlockY, a_BlockZ, a_World); case E_BLOCK_SIGN_POST: return new cSignEntity (a_BlockType, a_BlockX, a_BlockY, a_BlockZ, a_World);
case E_BLOCK_NOTE_BLOCK: return new cNoteEntity (a_BlockX, a_BlockY, a_BlockZ, a_World); case E_BLOCK_WALLSIGN: return new cSignEntity (a_BlockType, a_BlockX, a_BlockY, a_BlockZ, a_World);
case E_BLOCK_JUKEBOX: return new cJukeboxEntity (a_BlockX, a_BlockY, a_BlockZ, a_World); case E_BLOCK_NOTE_BLOCK: return new cNoteEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
case E_BLOCK_JUKEBOX: return new cJukeboxEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
} }
LOGD("%s: Requesting creation of an unknown block entity - block type %d (%s)", LOGD("%s: Requesting creation of an unknown block entity - block type %d (%s)",
__FUNCTION__, a_BlockType, ItemTypeToString(a_BlockType).c_str() __FUNCTION__, a_BlockType, ItemTypeToString(a_BlockType).c_str()

View File

@ -0,0 +1,197 @@
// CommandBlockEntity.cpp
// Implements the cCommandBlockEntity class representing a single command block in the world
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
#include "json/json.h"
#include "CommandBlockEntity.h"
#include "../Entities/Player.h"
#include "CommandOutput.h"
#include "Root.h"
#include "Server.h" // ExecuteConsoleCommand()
cCommandBlockEntity::cCommandBlockEntity(int a_X, int a_Y, int a_Z, cWorld * a_World) :
super(E_BLOCK_COMMAND_BLOCK, a_X, a_Y, a_Z, a_World),
m_ShouldExecute(false),
m_IsPowered(false)
{}
void cCommandBlockEntity::UsedBy(cPlayer * a_Player)
{
// Nothing to do
UNUSED(a_Player);
}
void cCommandBlockEntity::SetCommand(const AString & a_Cmd)
{
m_Command = a_Cmd;
}
void cCommandBlockEntity::SetLastOutput(const AString & a_LastOut)
{
m_LastOutput = a_LastOut;
}
void cCommandBlockEntity::SetResult(const NIBBLETYPE a_Result)
{
m_Result = a_Result;
}
const AString & cCommandBlockEntity::GetCommand(void) const
{
return m_Command;
}
const AString & cCommandBlockEntity::GetLastOutput(void) const
{
return m_LastOutput;
}
NIBBLETYPE cCommandBlockEntity::GetResult(void) const
{
return m_Result;
}
void cCommandBlockEntity::Activate(void)
{
m_ShouldExecute = true;
}
void cCommandBlockEntity::SetRedstonePower(bool a_IsPowered)
{
if (a_IsPowered && !m_IsPowered)
{
Activate();
}
m_IsPowered = a_IsPowered;
}
bool cCommandBlockEntity::Tick(float a_Dt, cChunk & a_Chunk)
{
if (!m_ShouldExecute)
{
return false;
}
m_ShouldExecute = false;
Execute();
return true;
}
void cCommandBlockEntity::SendTo(cClientHandle & a_Client)
{
// Nothing needs to be sent
UNUSED(a_Client);
}
bool cCommandBlockEntity::LoadFromJson(const Json::Value & a_Value)
{
m_Command = a_Value.get("Command", "").asString();
m_LastOutput = a_Value.get("LastOutput", "").asString();
return true;
}
void cCommandBlockEntity::SaveToJson(Json::Value & a_Value)
{
a_Value["Command"] = m_Command;
a_Value["LastOutput"] = m_LastOutput;
}
void cCommandBlockEntity::Execute()
{
class CommandBlockOutCb :
public cCommandOutputCallback
{
cCommandBlockEntity* m_CmdBlock;
public:
CommandBlockOutCb(cCommandBlockEntity* a_CmdBlock) : m_CmdBlock(a_CmdBlock) {}
virtual void Out(const AString & a_Text)
{
ASSERT(m_CmdBlock != NULL);
// Overwrite field
m_CmdBlock->SetLastOutput(a_Text);
}
} CmdBlockOutCb(this);
LOGD("cCommandBlockEntity: Executing command %s", m_Command.c_str());
cServer* Server = cRoot::Get()->GetServer();
Server->ExecuteConsoleCommand(m_Command, CmdBlockOutCb);
// TODO 2014-01-18 xdot: Update the signal strength.
m_Result = 0;
}

View File

@ -0,0 +1,91 @@
// CommandBlockEntity.h
// Declares the cCommandBlockEntity class representing a single command block in the world
#pragma once
#include "BlockEntity.h"
namespace Json
{
class Value;
}
// tolua_begin
class cCommandBlockEntity :
public cBlockEntity
{
typedef cBlockEntity super;
public:
// tolua_end
/// Creates a new empty command block entity
cCommandBlockEntity(int a_X, int a_Y, int a_Z, cWorld * a_World);
bool LoadFromJson( const Json::Value& a_Value );
virtual void SaveToJson(Json::Value& a_Value ) override;
virtual bool Tick(float a_Dt, cChunk & a_Chunk) override;
virtual void SendTo(cClientHandle & a_Client) override;
virtual void UsedBy(cPlayer * a_Player) override;
void SetLastOutput(const AString & a_LastOut);
void SetResult(const NIBBLETYPE a_Result);
// tolua_begin
/// Sets the internal redstone power flag to "on" or "off", depending on the parameter. Calls Activate() if appropriate
void SetRedstonePower(bool a_IsPowered);
/// Sets the command block to execute a command in the next tick
void Activate(void);
/// Sets the command
void SetCommand(const AString & a_Cmd);
/// Retrieves stored command
const AString & GetCommand(void) const;
/// Retrieves the last line of output generated by the command block
const AString & GetLastOutput(void) const;
/// Retrieves the result (signal strength) of the last operation
NIBBLETYPE GetResult(void) const;
// tolua_end
private:
/// Executes the associated command
void Execute();
bool m_ShouldExecute;
bool m_IsPowered;
AString m_Command;
AString m_LastOutput;
NIBBLETYPE m_Result;
} ; // tolua_export

View File

@ -1298,6 +1298,7 @@ void cChunk::CreateBlockEntities(void)
switch (BlockType) switch (BlockType)
{ {
case E_BLOCK_CHEST: case E_BLOCK_CHEST:
case E_BLOCK_COMMAND_BLOCK:
case E_BLOCK_DISPENSER: case E_BLOCK_DISPENSER:
case E_BLOCK_DROPPER: case E_BLOCK_DROPPER:
case E_BLOCK_ENDER_CHEST: case E_BLOCK_ENDER_CHEST:
@ -1425,6 +1426,7 @@ void cChunk::SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType,
switch (a_BlockType) switch (a_BlockType)
{ {
case E_BLOCK_CHEST: case E_BLOCK_CHEST:
case E_BLOCK_COMMAND_BLOCK:
case E_BLOCK_DISPENSER: case E_BLOCK_DISPENSER:
case E_BLOCK_DROPPER: case E_BLOCK_DROPPER:
case E_BLOCK_ENDER_CHEST: case E_BLOCK_ENDER_CHEST:
@ -2268,6 +2270,38 @@ bool cChunk::DoWithNoteBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cNoteBl
bool cChunk::DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cCommandBlockCallback & 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_COMMAND_BLOCK)
{
// 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((cCommandBlockEntity *)*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

View File

@ -40,12 +40,13 @@ class cFluidSimulatorData;
class cMobCensus; class cMobCensus;
class cMobSpawner; class cMobSpawner;
typedef std::list<cClientHandle *> cClientHandleList; typedef std::list<cClientHandle *> cClientHandleList;
typedef cItemCallback<cEntity> cEntityCallback; typedef cItemCallback<cEntity> cEntityCallback;
typedef cItemCallback<cChestEntity> cChestCallback; typedef cItemCallback<cChestEntity> cChestCallback;
typedef cItemCallback<cDispenserEntity> cDispenserCallback; typedef cItemCallback<cDispenserEntity> cDispenserCallback;
typedef cItemCallback<cFurnaceEntity> cFurnaceCallback; typedef cItemCallback<cFurnaceEntity> cFurnaceCallback;
typedef cItemCallback<cNoteEntity> cNoteBlockCallback; typedef cItemCallback<cNoteEntity> cNoteBlockCallback;
typedef cItemCallback<cCommandBlockEntity> cCommandBlockCallback;
@ -237,6 +238,9 @@ public:
/// Calls the callback for the noteblock at the specified coords; returns false if there's no noteblock at those coords or callback returns true, returns true if found /// Calls the callback for the noteblock at the specified coords; returns false if there's no noteblock at those coords or callback returns true, returns true if found
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
bool DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cCommandBlockCallback & 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

View File

@ -1968,6 +1968,23 @@ bool cChunkMap::DoWithNoteBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cNot
bool cChunkMap::DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cCommandBlockCallback & 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->DoWithCommandBlockAt(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)
{ {

View File

@ -23,6 +23,7 @@ class cDropperEntity;
class cDropSpenserEntity; class cDropSpenserEntity;
class cFurnaceEntity; class cFurnaceEntity;
class cNoteEntity; class cNoteEntity;
class cCommandBlockEntity;
class cPawn; class cPawn;
class cPickup; class cPickup;
class cChunkDataSerializer; class cChunkDataSerializer;
@ -32,15 +33,16 @@ class cMobSpawner;
typedef std::list<cClientHandle *> cClientHandleList; typedef std::list<cClientHandle *> cClientHandleList;
typedef cChunk * cChunkPtr; typedef cChunk * cChunkPtr;
typedef cItemCallback<cEntity> cEntityCallback; typedef cItemCallback<cEntity> cEntityCallback;
typedef cItemCallback<cBlockEntity> cBlockEntityCallback; typedef cItemCallback<cBlockEntity> cBlockEntityCallback;
typedef cItemCallback<cChestEntity> cChestCallback; typedef cItemCallback<cChestEntity> cChestCallback;
typedef cItemCallback<cDispenserEntity> cDispenserCallback; typedef cItemCallback<cDispenserEntity> cDispenserCallback;
typedef cItemCallback<cDropperEntity> cDropperCallback; typedef cItemCallback<cDropperEntity> cDropperCallback;
typedef cItemCallback<cDropSpenserEntity> cDropSpenserCallback; typedef cItemCallback<cDropSpenserEntity> cDropSpenserCallback;
typedef cItemCallback<cFurnaceEntity> cFurnaceCallback; typedef cItemCallback<cFurnaceEntity> cFurnaceCallback;
typedef cItemCallback<cNoteEntity> cNoteBlockCallback; typedef cItemCallback<cNoteEntity> cNoteBlockCallback;
typedef cItemCallback<cChunk> cChunkCallback; typedef cItemCallback<cCommandBlockEntity> cCommandBlockCallback;
typedef cItemCallback<cChunk> cChunkCallback;
@ -236,6 +238,9 @@ public:
/// Calls the callback for the noteblock at the specified coords; returns false if there's no noteblock at those coords or callback returns true, returns true if found /// Calls the callback for the noteblock at the specified coords; returns false if there's no noteblock at those coords or callback returns true, returns true if found
bool DoWithNoteBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cNoteBlockCallback & a_Callback); // Lua-accessible bool DoWithNoteBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cNoteBlockCallback & a_Callback); // Lua-accessible
/// 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
/// 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

View File

@ -8,6 +8,7 @@
#include "Entities/Player.h" #include "Entities/Player.h"
#include "Inventory.h" #include "Inventory.h"
#include "BlockEntities/ChestEntity.h" #include "BlockEntities/ChestEntity.h"
#include "BlockEntities/CommandBlockEntity.h"
#include "BlockEntities/SignEntity.h" #include "BlockEntities/SignEntity.h"
#include "UI/Window.h" #include "UI/Window.h"
#include "Item.h" #include "Item.h"
@ -545,6 +546,15 @@ void cClientHandle::HandlePlayerPos(double a_PosX, double a_PosY, double a_PosZ,
void cClientHandle::HandlePluginMessage(const AString & a_Channel, const AString & a_Message) void cClientHandle::HandlePluginMessage(const AString & a_Channel, const AString & a_Message)
{ {
if (a_Channel == "MC|AdvCdm") // Command block
{
const char* Data = a_Message.c_str();
HandleCommandBlockMessage(Data, a_Message.size());
return;
}
cPluginManager::Get()->CallHookPluginMessage(*this, a_Channel, a_Message); cPluginManager::Get()->CallHookPluginMessage(*this, a_Channel, a_Message);
} }
@ -552,6 +562,67 @@ void cClientHandle::HandlePluginMessage(const AString & a_Channel, const AString
void cClientHandle::HandleCommandBlockMessage(const char* a_Data, unsigned int a_Length)
{
if (a_Length < 14)
{
LOGD("Malformed MC|AdvCdm packet.");
return;
}
cByteBuffer Buffer(a_Length);
Buffer.Write(a_Data, a_Length);
int BlockX, BlockY, BlockZ;
AString Command;
char Mode;
Buffer.ReadChar(Mode);
switch (Mode)
{
case 0x00:
{
Buffer.ReadBEInt(BlockX);
Buffer.ReadBEInt(BlockY);
Buffer.ReadBEInt(BlockZ);
Buffer.ReadVarUTF8String(Command);
break;
}
default:
{
LOGD("Unhandled MC|AdvCdm packet mode.");
return;
}
}
class cUpdateCommandBlock :
public cCommandBlockCallback
{
AString m_Command;
public:
cUpdateCommandBlock(const AString & a_Command) : m_Command(a_Command) {}
virtual bool Item(cCommandBlockEntity * a_CommandBlock) override
{
a_CommandBlock->SetCommand(m_Command);
return false;
}
} CmdBlockCB (Command);
cWorld * World = m_Player->GetWorld();
World->DoWithCommandBlockAt(BlockX, BlockY, BlockZ, CmdBlockCB);
}
void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status) void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status)
{ {
LOGD("HandleLeftClick: {%i, %i, %i}; Face: %i; Stat: %i", LOGD("HandleLeftClick: {%i, %i, %i}; Face: %i; Stat: %i",

View File

@ -325,6 +325,9 @@ private:
/// Handles the DIG_FINISHED dig packet: /// Handles the DIG_FINISHED dig packet:
void HandleBlockDigFinished(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_OldBlock, NIBBLETYPE a_OldMeta); void HandleBlockDigFinished(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_OldBlock, NIBBLETYPE a_OldMeta);
/// Handles the "MC|AdvCdm" plugin message
void HandleCommandBlockMessage(const char* a_Data, unsigned int a_Length);
// cSocketThreads::cCallback overrides: // cSocketThreads::cCallback overrides:
virtual void DataReceived (const char * a_Data, int a_Size) override; // Data is received from the client virtual void DataReceived (const char * a_Data, int a_Size) override; // Data is received from the client
virtual void GetOutgoingData(AString & a_Data) override; // Data can be sent to client virtual void GetOutgoingData(AString & a_Data) override; // Data can be sent to client

View File

@ -4,6 +4,7 @@
#include "RedstoneSimulator.h" #include "RedstoneSimulator.h"
#include "../BlockEntities/DropSpenserEntity.h" #include "../BlockEntities/DropSpenserEntity.h"
#include "../BlockEntities/NoteEntity.h" #include "../BlockEntities/NoteEntity.h"
#include "../BlockEntities/CommandBlockEntity.h"
#include "../Entities/TNTEntity.h" #include "../Entities/TNTEntity.h"
#include "../Blocks/BlockTorch.h" #include "../Blocks/BlockTorch.h"
#include "../Blocks/BlockDoor.h" #include "../Blocks/BlockDoor.h"
@ -215,11 +216,12 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c
{ {
case E_BLOCK_BLOCK_OF_REDSTONE: HandleRedstoneBlock(a_X, dataitr->y, a_Z); break; case E_BLOCK_BLOCK_OF_REDSTONE: HandleRedstoneBlock(a_X, dataitr->y, a_Z); break;
case E_BLOCK_LEVER: HandleRedstoneLever(a_X, dataitr->y, a_Z); break; case E_BLOCK_LEVER: HandleRedstoneLever(a_X, dataitr->y, a_Z); break;
case E_BLOCK_TNT: HandleTNT(a_X, dataitr->y, a_Z); break; case E_BLOCK_TNT: HandleTNT(a_X, dataitr->y, a_Z); break;
case E_BLOCK_TRAPDOOR: HandleTrapdoor(a_X, dataitr->y, a_Z); break; case E_BLOCK_TRAPDOOR: HandleTrapdoor(a_X, dataitr->y, a_Z); break;
case E_BLOCK_REDSTONE_WIRE: HandleRedstoneWire(a_X, dataitr->y, a_Z); break; case E_BLOCK_REDSTONE_WIRE: HandleRedstoneWire(a_X, dataitr->y, a_Z); break;
case E_BLOCK_NOTE_BLOCK: HandleNoteBlock(a_X, dataitr->y, a_Z); break; case E_BLOCK_NOTE_BLOCK: HandleNoteBlock(a_X, dataitr->y, a_Z); break;
case E_BLOCK_DAYLIGHT_SENSOR: HandleDaylightSensor(a_X, dataitr->y, a_Z); break; case E_BLOCK_DAYLIGHT_SENSOR: HandleDaylightSensor(a_X, dataitr->y, a_Z); break;
case E_BLOCK_COMMAND_BLOCK: HandleCommandBlock(a_X, dataitr->y, a_Z); break;
case E_BLOCK_REDSTONE_TORCH_OFF: case E_BLOCK_REDSTONE_TORCH_OFF:
case E_BLOCK_REDSTONE_TORCH_ON: case E_BLOCK_REDSTONE_TORCH_ON:
@ -763,6 +765,29 @@ void cRedstoneSimulator::HandleDoor(int a_BlockX, int a_BlockY, int a_BlockZ)
void cRedstoneSimulator::HandleCommandBlock(int a_BlockX, int a_BlockY, int a_BlockZ)
{
class cSetPowerToCommandBlock :
public cCommandBlockCallback
{
bool m_IsPowered;
public:
cSetPowerToCommandBlock(bool a_IsPowered) : m_IsPowered(a_IsPowered) {}
virtual bool Item(cCommandBlockEntity * a_CommandBlock) override
{
a_CommandBlock->SetRedstonePower(m_IsPowered);
return false;
}
} CmdBlockSP (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ));
m_World.DoWithCommandBlockAt(a_BlockX, a_BlockY, a_BlockZ, CmdBlockSP);
}
void cRedstoneSimulator::HandleRail(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyType) void cRedstoneSimulator::HandleRail(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyType)
{ {
switch (a_MyType) switch (a_MyType)

View File

@ -110,6 +110,8 @@ private:
void HandleRedstoneLamp(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyState); void HandleRedstoneLamp(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyState);
/** Handles doords */ /** Handles doords */
void HandleDoor(int a_BlockX, int a_BlockY, int a_BlockZ); void HandleDoor(int a_BlockX, int a_BlockY, int a_BlockZ);
/** Handles command blocks */
void HandleCommandBlock(int a_BlockX, int a_BlockY, int a_BlockZ);
/** Handles activator, detector, and powered rails */ /** Handles activator, detector, and powered rails */
void HandleRail(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyType); void HandleRail(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyType);
/** Handles trapdoors */ /** Handles trapdoors */
@ -166,6 +168,7 @@ private:
switch (Block) switch (Block)
{ {
case E_BLOCK_ACTIVATOR_RAIL: case E_BLOCK_ACTIVATOR_RAIL:
case E_BLOCK_COMMAND_BLOCK:
case E_BLOCK_PISTON: case E_BLOCK_PISTON:
case E_BLOCK_STICKY_PISTON: case E_BLOCK_STICKY_PISTON:
case E_BLOCK_DISPENSER: case E_BLOCK_DISPENSER:
@ -220,6 +223,7 @@ private:
case E_BLOCK_ACTIVATOR_RAIL: case E_BLOCK_ACTIVATOR_RAIL:
case E_BLOCK_ACTIVE_COMPARATOR: case E_BLOCK_ACTIVE_COMPARATOR:
case E_BLOCK_BLOCK_OF_REDSTONE: case E_BLOCK_BLOCK_OF_REDSTONE:
case E_BLOCK_COMMAND_BLOCK:
case E_BLOCK_DETECTOR_RAIL: case E_BLOCK_DETECTOR_RAIL:
case E_BLOCK_DISPENSER: case E_BLOCK_DISPENSER:
case E_BLOCK_DAYLIGHT_SENSOR: case E_BLOCK_DAYLIGHT_SENSOR:

View File

@ -1149,6 +1149,15 @@ bool cWorld::DoWithNoteBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cNoteBl
bool cWorld::DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cCommandBlockCallback & a_Callback)
{
return m_ChunkMap->DoWithCommandBlockAt(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);

View File

@ -46,12 +46,13 @@ class cMobCensus;
typedef std::list< cPlayer * > cPlayerList; typedef std::list< cPlayer * > cPlayerList;
typedef cItemCallback<cPlayer> cPlayerListCallback; typedef cItemCallback<cPlayer> cPlayerListCallback;
typedef cItemCallback<cEntity> cEntityCallback; typedef cItemCallback<cEntity> cEntityCallback;
typedef cItemCallback<cChestEntity> cChestCallback; typedef cItemCallback<cChestEntity> cChestCallback;
typedef cItemCallback<cDispenserEntity> cDispenserCallback; typedef cItemCallback<cDispenserEntity> cDispenserCallback;
typedef cItemCallback<cFurnaceEntity> cFurnaceCallback; typedef cItemCallback<cFurnaceEntity> cFurnaceCallback;
typedef cItemCallback<cNoteEntity> cNoteBlockCallback; typedef cItemCallback<cNoteEntity> cNoteBlockCallback;
typedef cItemCallback<cCommandBlockEntity> cCommandBlockCallback;
@ -467,6 +468,9 @@ public:
/// Calls the callback for the noteblock at the specified coords; returns false if there's no noteblock at those coords or callback returns true, returns true if found /// Calls the callback for the noteblock at the specified coords; returns false if there's no noteblock at those coords or callback returns true, returns true if found
bool DoWithNoteBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cNoteBlockCallback & a_Callback); // Exported in ManualBindings.cpp bool DoWithNoteBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cNoteBlockCallback & a_Callback); // Exported in ManualBindings.cpp
/// 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
/// 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

View File

@ -10,6 +10,7 @@
#include "FastNBT.h" #include "FastNBT.h"
#include "../BlockEntities/ChestEntity.h" #include "../BlockEntities/ChestEntity.h"
#include "../BlockEntities/CommandBlockEntity.h"
#include "../BlockEntities/DispenserEntity.h" #include "../BlockEntities/DispenserEntity.h"
#include "../BlockEntities/DropperEntity.h" #include "../BlockEntities/DropperEntity.h"
#include "../BlockEntities/FurnaceEntity.h" #include "../BlockEntities/FurnaceEntity.h"
@ -219,8 +220,23 @@ void cNBTChunkSerializer::AddJukeboxEntity(cJukeboxEntity * a_Jukebox)
void cNBTChunkSerializer::AddNoteEntity(cNoteEntity * a_Note) void cNBTChunkSerializer::AddNoteEntity(cNoteEntity * a_Note)
{ {
m_Writer.BeginCompound(""); m_Writer.BeginCompound("");
AddBasicTileEntity(a_Note, "Music"); AddBasicTileEntity(a_Note, "Music");
m_Writer.AddByte("note", a_Note->GetPitch()); m_Writer.AddByte("note", a_Note->GetPitch());
m_Writer.EndCompound();
}
void cNBTChunkSerializer::AddCommandBlockEntity(cCommandBlockEntity * a_CmdBlock)
{
m_Writer.BeginCompound("");
AddBasicTileEntity(a_CmdBlock, "Control");
m_Writer.AddString("Command", a_CmdBlock->GetCommand());
m_Writer.AddInt ("SuccessCount", a_CmdBlock->GetResult());
m_Writer.AddString("LastOutput", a_CmdBlock->GetLastOutput());
m_Writer.AddByte ("TrackOutput", 1); // TODO 2014-01-18 xdot: Figure out what TrackOutput is and save it.
m_Writer.EndCompound(); m_Writer.EndCompound();
} }
@ -639,15 +655,16 @@ void cNBTChunkSerializer::BlockEntity(cBlockEntity * a_Entity)
// Add tile-entity into NBT: // Add tile-entity into NBT:
switch (a_Entity->GetBlockType()) switch (a_Entity->GetBlockType())
{ {
case E_BLOCK_CHEST: AddChestEntity ((cChestEntity *) a_Entity); break; case E_BLOCK_CHEST: AddChestEntity ((cChestEntity *) a_Entity); break;
case E_BLOCK_DISPENSER: AddDispenserEntity ((cDispenserEntity *) a_Entity); break; case E_BLOCK_DISPENSER: AddDispenserEntity ((cDispenserEntity *) a_Entity); break;
case E_BLOCK_DROPPER: AddDropperEntity ((cDropperEntity *) a_Entity); break; case E_BLOCK_DROPPER: AddDropperEntity ((cDropperEntity *) a_Entity); break;
case E_BLOCK_FURNACE: AddFurnaceEntity ((cFurnaceEntity *) a_Entity); break; case E_BLOCK_FURNACE: AddFurnaceEntity ((cFurnaceEntity *) a_Entity); break;
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_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;
default: default:
{ {
ASSERT(!"Unhandled block entity saved into Anvil"); ASSERT(!"Unhandled block entity saved into Anvil");

View File

@ -21,6 +21,7 @@ class cEntity;
class cBlockEntity; class cBlockEntity;
class cBoat; class cBoat;
class cChestEntity; class cChestEntity;
class cCommandBlockEntity;
class cDispenserEntity; class cDispenserEntity;
class cDropperEntity; class cDropperEntity;
class cFurnaceEntity; class cFurnaceEntity;
@ -92,6 +93,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 AddCommandBlockEntity(cCommandBlockEntity * a_CmdBlock);
// Entities: // Entities:
void AddBasicEntity (cEntity * a_Entity, const AString & a_ClassName); void AddBasicEntity (cEntity * a_Entity, const AString & a_ClassName);

View File

@ -15,6 +15,7 @@
#include "../StringCompression.h" #include "../StringCompression.h"
#include "../BlockEntities/ChestEntity.h" #include "../BlockEntities/ChestEntity.h"
#include "../BlockEntities/CommandBlockEntity.h"
#include "../BlockEntities/DispenserEntity.h" #include "../BlockEntities/DispenserEntity.h"
#include "../BlockEntities/DropperEntity.h" #include "../BlockEntities/DropperEntity.h"
#include "../BlockEntities/FurnaceEntity.h" #include "../BlockEntities/FurnaceEntity.h"
@ -567,6 +568,10 @@ void cWSSAnvil::LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntities, con
{ {
LoadChestFromNBT(a_BlockEntities, a_NBT, Child); LoadChestFromNBT(a_BlockEntities, a_NBT, Child);
} }
else if (strncmp(a_NBT.GetData(sID), "Control", a_NBT.GetDataLength(sID)) == 0)
{
LoadCommandBlockFromNBT(a_BlockEntities, a_NBT, Child);
}
else if (strncmp(a_NBT.GetData(sID), "Dropper", a_NBT.GetDataLength(sID)) == 0) else if (strncmp(a_NBT.GetData(sID), "Dropper", a_NBT.GetDataLength(sID)) == 0)
{ {
LoadDropperFromNBT(a_BlockEntities, a_NBT, Child); LoadDropperFromNBT(a_BlockEntities, a_NBT, Child);
@ -915,6 +920,43 @@ void cWSSAnvil::LoadSignFromNBT(cBlockEntityList & a_BlockEntities, const cParse
void cWSSAnvil::LoadCommandBlockFromNBT(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<cCommandBlockEntity> CmdBlock(new cCommandBlockEntity(x, y, z, m_World));
int currentLine = a_NBT.FindChildByName(a_TagIdx, "Command");
if (currentLine >= 0)
{
CmdBlock->SetCommand(a_NBT.GetString(currentLine));
}
currentLine = a_NBT.FindChildByName(a_TagIdx, "SuccessCount");
if (currentLine >= 0)
{
CmdBlock->SetResult(a_NBT.GetInt(currentLine));
}
currentLine = a_NBT.FindChildByName(a_TagIdx, "LastOutput");
if (currentLine >= 0)
{
CmdBlock->SetLastOutput(a_NBT.GetString(currentLine));
}
// TODO 2014-01-18 xdot: Figure out what TrackOutput is and parse it.
a_BlockEntities.push_back(CmdBlock.release());
}
void cWSSAnvil::LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_EntityTagIdx, const char * a_IDTag, int a_IDTagLength) void cWSSAnvil::LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_EntityTagIdx, const char * a_IDTag, int a_IDTagLength)
{ {
if (strncmp(a_IDTag, "Boat", a_IDTagLength) == 0) if (strncmp(a_IDTag, "Boat", a_IDTagLength) == 0)

View File

@ -131,14 +131,15 @@ protected:
*/ */
void LoadItemGridFromNBT(cItemGrid & a_ItemGrid, const cParsedNBT & a_NBT, int a_ItemsTagIdx, int s_SlotOffset = 0); void LoadItemGridFromNBT(cItemGrid & a_ItemGrid, const cParsedNBT & a_NBT, int a_ItemsTagIdx, int s_SlotOffset = 0);
void LoadChestFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadChestFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
void LoadDispenserFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadDispenserFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
void LoadDropperFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadDropperFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
void LoadFurnaceFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE * a_BlockTypes, NIBBLETYPE * a_BlockMetas); void LoadFurnaceFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE * a_BlockTypes, NIBBLETYPE * a_BlockMetas);
void LoadHopperFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadHopperFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
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 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);