From 9a9b51a5134d8afd8f089d247c59668bd7da695d Mon Sep 17 00:00:00 2001 From: andrew Date: Sat, 18 Jan 2014 15:16:47 +0200 Subject: Basic command block implementation --- src/BlockEntities/BlockEntity.cpp | 24 +++-- src/BlockEntities/CommandBlockEntity.cpp | 173 +++++++++++++++++++++++++++++++ src/BlockEntities/CommandBlockEntity.h | 85 +++++++++++++++ 3 files changed, 271 insertions(+), 11 deletions(-) create mode 100644 src/BlockEntities/CommandBlockEntity.cpp create mode 100644 src/BlockEntities/CommandBlockEntity.h (limited to 'src/BlockEntities') 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..6e371e0fe --- /dev/null +++ b/src/BlockEntities/CommandBlockEntity.cpp @@ -0,0 +1,173 @@ + +// 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" + + + + + +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) + { + //OpenWindow(new cDropSpenserWindow(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;LOGD("Hrey %s", a_Cmd.c_str()); +} + + + + + +const AString & cCommandBlockEntity::GetCommand(void) const +{ + return m_Command; +} + + + + + +const AString & cCommandBlockEntity::GetLastOutput(void) const +{ + return m_LastOutput; +} + + + + + +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() +{ + // TODO: Parse arguments and dispatch command + LOGD("Command: %s", m_Command.c_str()); + m_LastOutput = ""; +} + + + + diff --git a/src/BlockEntities/CommandBlockEntity.h b/src/BlockEntities/CommandBlockEntity.h new file mode 100644 index 000000000..266a3c33d --- /dev/null +++ b/src/BlockEntities/CommandBlockEntity.h @@ -0,0 +1,85 @@ + +// 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; + + // 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; + + // tolua_end + +private: + + /// Executes the associated command + void Execute(); + + bool m_ShouldExecute; + bool m_IsPowered; + + AString m_Command; + + AString m_LastOutput; +} ; // tolua_export + + + + -- cgit v1.2.3