diff options
Diffstat (limited to 'src/BlockEntities')
-rw-r--r-- | src/BlockEntities/BlockEntity.cpp | 24 | ||||
-rw-r--r-- | src/BlockEntities/CommandBlockEntity.cpp | 197 | ||||
-rw-r--r-- | src/BlockEntities/CommandBlockEntity.h | 91 | ||||
-rw-r--r-- | src/BlockEntities/FurnaceEntity.cpp | 4 | ||||
-rw-r--r-- | src/BlockEntities/HopperEntity.cpp | 4 |
5 files changed, 305 insertions, 15 deletions
diff --git a/src/BlockEntities/BlockEntity.cpp b/src/BlockEntities/BlockEntity.cpp index 5d7e4a37a..97b5c1a66 100644 --- a/src/BlockEntities/BlockEntity.cpp +++ b/src/BlockEntities/BlockEntity.cpp @@ -6,6 +6,7 @@ #include "Globals.h" #include "BlockEntity.h" #include "ChestEntity.h" +#include "CommandBlockEntity.h" #include "DispenserEntity.h" #include "DropperEntity.h" #include "EnderChestEntity.h" @@ -23,17 +24,18 @@ cBlockEntity * cBlockEntity::CreateByBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE { switch (a_BlockType) { - 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_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_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_HOPPER: return new cHopperEntity (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_WALLSIGN: 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_JUKEBOX: return new cJukeboxEntity (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_COMMAND_BLOCK: return new cCommandBlockEntity(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_ENDER_CHEST: return new cEnderChestEntity (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_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_SIGN_POST: return new cSignEntity (a_BlockType, 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_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)", __FUNCTION__, a_BlockType, ItemTypeToString(a_BlockType).c_str() diff --git a/src/BlockEntities/CommandBlockEntity.cpp b/src/BlockEntities/CommandBlockEntity.cpp new file mode 100644 index 000000000..ca617b04d --- /dev/null +++ b/src/BlockEntities/CommandBlockEntity.cpp @@ -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; +} + + + + diff --git a/src/BlockEntities/CommandBlockEntity.h b/src/BlockEntities/CommandBlockEntity.h new file mode 100644 index 000000000..12157670f --- /dev/null +++ b/src/BlockEntities/CommandBlockEntity.h @@ -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 + + + + diff --git a/src/BlockEntities/FurnaceEntity.cpp b/src/BlockEntities/FurnaceEntity.cpp index f15553968..c6643bcff 100644 --- a/src/BlockEntities/FurnaceEntity.cpp +++ b/src/BlockEntities/FurnaceEntity.cpp @@ -307,7 +307,7 @@ void cFurnaceEntity::OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum) /// Updates the current recipe, based on the current input void cFurnaceEntity::UpdateInput(void) { - if (!m_Contents.GetSlot(fsInput).IsStackableWith(m_LastInput)) + if (!m_Contents.GetSlot(fsInput).IsEqual(m_LastInput)) { // The input is different from what we had before, reset the cooking time m_TimeCooked = 0; @@ -417,7 +417,7 @@ bool cFurnaceEntity::CanCookInputToOutput(void) const return true; } - if (!m_Contents.GetSlot(fsOutput).IsStackableWith(*m_CurrentRecipe->Out)) + if (!m_Contents.GetSlot(fsOutput).IsEqual(*m_CurrentRecipe->Out)) { // The output slot is blocked with something that cannot be stacked with the recipe's output return false; diff --git a/src/BlockEntities/HopperEntity.cpp b/src/BlockEntities/HopperEntity.cpp index eac59e74d..2255cad64 100644 --- a/src/BlockEntities/HopperEntity.cpp +++ b/src/BlockEntities/HopperEntity.cpp @@ -407,7 +407,7 @@ bool cHopperEntity::MoveItemsFromSlot(cBlockEntityWithItems & a_Entity, int a_Sl m_Contents.SetSlot(i, One); return true; } - else if (m_Contents.GetSlot(i).IsStackableWith(One)) + else if (m_Contents.GetSlot(i).IsEqual(One)) { if (cPluginManager::Get()->CallHookHopperPullingItem(*m_World, *this, i, a_Entity, a_SlotNum)) { @@ -544,7 +544,7 @@ bool cHopperEntity::MoveItemsToSlot(cBlockEntityWithItems & a_Entity, int a_DstS } for (int i = 0; i < ContentsWidth * ContentsHeight; i++) { - if (m_Contents.GetSlot(i).IsStackableWith(DestSlot)) + if (m_Contents.GetSlot(i).IsEqual(DestSlot)) { if (cPluginManager::Get()->CallHookHopperPushingItem(*m_World, *this, i, a_Entity, a_DstSlotNum)) { |