summaryrefslogtreecommitdiffstats
path: root/src/BlockEntities
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/BlockEntities/BlockEntity.cpp24
-rw-r--r--src/BlockEntities/CommandBlockEntity.cpp227
-rw-r--r--src/BlockEntities/CommandBlockEntity.h94
3 files changed, 334 insertions, 11 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..c29e3dff8
--- /dev/null
+++ b/src/BlockEntities/CommandBlockEntity.cpp
@@ -0,0 +1,227 @@
+
+// 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)
+{
+ SetBlockEntity(this); // cBlockEntityWindowOwner
+}
+
+
+
+
+
+
+cCommandBlockEntity::~cCommandBlockEntity()
+{
+ // Tell window its owner is destroyed
+ cWindow * Window = GetWindow();
+ if (Window != NULL)
+ {
+ Window->OwnerDestroyed();
+ }
+}
+
+
+
+
+
+
+void cCommandBlockEntity::UsedBy(cPlayer * a_Player)
+{
+ cWindow * Window = GetWindow();
+ if (Window == NULL)
+ {
+ // TODO 2014-01-18 xdot: Open the appropriate window.
+ // OpenWindow(new cCommandBlockWindow(m_PosX, m_PosY, m_PosZ, this));
+ Window = GetWindow();
+ }
+
+ if (Window != NULL)
+ {
+ if (a_Player->GetWindow() != Window)
+ {
+ a_Player->OpenWindow(Window);
+ }
+ }
+}
+
+
+
+
+
+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..c4529a1e6
--- /dev/null
+++ b/src/BlockEntities/CommandBlockEntity.h
@@ -0,0 +1,94 @@
+
+// CommandBlockEntity.h
+
+// Declares the cCommandBlockEntity class representing a single command block in the world
+
+
+
+
+
+#pragma once
+
+#include "BlockEntityWithItems.h"
+#include "../UI/WindowOwner.h"
+
+
+
+
+
+namespace Json
+{
+ class Value;
+}
+
+
+
+
+
+// tolua_begin
+
+class cCommandBlockEntity :
+ public cBlockEntity,
+ public cBlockEntityWindowOwner
+{
+ 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);
+ virtual ~cCommandBlockEntity();
+
+ 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
+
+
+
+