summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMattes D <github@xoft.cz>2016-06-16 21:54:09 +0200
committerGitHub <noreply@github.com>2016-06-16 21:54:09 +0200
commitec998e821fd905966ed14ed47a29520ec1d1d782 (patch)
treeb61d763a27e1986116c1a2f3b779bcf0bb1bd27b /src
parentMerge pull request #3227 from cuberite/NormalizeVectorApi (diff)
parent- Add a activation flag to droppers and dispensers. Previously droppers and dispensers shot items with every block update. (diff)
downloadcuberite-ec998e821fd905966ed14ed47a29520ec1d1d782.tar
cuberite-ec998e821fd905966ed14ed47a29520ec1d1d782.tar.gz
cuberite-ec998e821fd905966ed14ed47a29520ec1d1d782.tar.bz2
cuberite-ec998e821fd905966ed14ed47a29520ec1d1d782.tar.lz
cuberite-ec998e821fd905966ed14ed47a29520ec1d1d782.tar.xz
cuberite-ec998e821fd905966ed14ed47a29520ec1d1d782.tar.zst
cuberite-ec998e821fd905966ed14ed47a29520ec1d1d782.zip
Diffstat (limited to '')
-rw-r--r--src/BlockEntities/DispenserEntity.cpp2
-rw-r--r--src/BlockEntities/DropSpenserEntity.cpp6
-rw-r--r--src/BlockID.h2
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/DropSpenserHandler.h27
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.cpp6
5 files changed, 34 insertions, 9 deletions
diff --git a/src/BlockEntities/DispenserEntity.cpp b/src/BlockEntities/DispenserEntity.cpp
index e03644a0f..d6fbafadf 100644
--- a/src/BlockEntities/DispenserEntity.cpp
+++ b/src/BlockEntities/DispenserEntity.cpp
@@ -283,7 +283,7 @@ UInt32 cDispenserEntity::SpawnProjectileFromDispenser(int a_BlockX, int a_BlockY
Vector3d cDispenserEntity::GetShootVector(NIBBLETYPE a_Meta)
{
- switch (a_Meta & 0x7)
+ switch (a_Meta & E_META_DROPSPENSER_FACING_MASK)
{
case E_META_DROPSPENSER_FACING_YP: return Vector3d( 0, 1, 0);
case E_META_DROPSPENSER_FACING_YM: return Vector3d( 0, -1, 0);
diff --git a/src/BlockEntities/DropSpenserEntity.cpp b/src/BlockEntities/DropSpenserEntity.cpp
index 8dddf85de..3a43e1073 100644
--- a/src/BlockEntities/DropSpenserEntity.cpp
+++ b/src/BlockEntities/DropSpenserEntity.cpp
@@ -41,7 +41,7 @@ cDropSpenserEntity::~cDropSpenserEntity()
void cDropSpenserEntity::AddDropSpenserDir(int & a_BlockX, int & a_BlockY, int & a_BlockZ, NIBBLETYPE a_Direction)
{
- switch (a_Direction & 0x07) // Vanilla uses the 8th bit to determine power state - we don't
+ switch (a_Direction & E_META_DROPSPENSER_FACING_MASK)
{
case E_META_DROPSPENSER_FACING_YM: a_BlockY--; return;
case E_META_DROPSPENSER_FACING_YP: a_BlockY++; return;
@@ -87,7 +87,7 @@ void cDropSpenserEntity::DropSpense(cChunk & a_Chunk)
// Broadcast a smoke and click effects:
NIBBLETYPE Meta = a_Chunk.GetMeta(m_RelX, m_PosY, m_RelZ);
int SmokeDir = 0;
- switch (Meta)
+ switch (Meta & E_META_DROPSPENSER_FACING_MASK)
{
case E_META_DROPSPENSER_FACING_YP: SmokeDir = static_cast<int>(SmokeDirection::CENTRE); break; // YP & YM don't have associated smoke dirs, just do 4 (centre of block)
case E_META_DROPSPENSER_FACING_YM: SmokeDir = static_cast<int>(SmokeDirection::CENTRE); break;
@@ -176,7 +176,7 @@ void cDropSpenserEntity::DropFromSlot(cChunk & a_Chunk, int a_SlotNum)
const int PickupSpeed = m_World->GetTickRandomNumber(4) + 2; // At least 2, at most 6
int PickupSpeedX = 0, PickupSpeedY = 0, PickupSpeedZ = 0;
- switch (Meta)
+ switch (Meta & E_META_DROPSPENSER_FACING_MASK)
{
case E_META_DROPSPENSER_FACING_YP: PickupSpeedY = PickupSpeed; break;
case E_META_DROPSPENSER_FACING_YM: PickupSpeedY = -PickupSpeed; break;
diff --git a/src/BlockID.h b/src/BlockID.h
index b32b673c6..5af0cc4f5 100644
--- a/src/BlockID.h
+++ b/src/BlockID.h
@@ -536,6 +536,8 @@ enum
E_META_DROPSPENSER_FACING_ZP = 3,
E_META_DROPSPENSER_FACING_XM = 4,
E_META_DROPSPENSER_FACING_XP = 5,
+ E_META_DROPSPENSER_FACING_MASK = 7,
+ E_META_DROPSPENSER_ACTIVATED = 8,
// E_BLOCK_DOUBLE_STONE_SLAB metas:
E_META_DOUBLE_STONE_SLAB_STONE = 0,
diff --git a/src/Simulator/IncrementalRedstoneSimulator/DropSpenserHandler.h b/src/Simulator/IncrementalRedstoneSimulator/DropSpenserHandler.h
index b67b8d4fb..3c9952582 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/DropSpenserHandler.h
+++ b/src/Simulator/IncrementalRedstoneSimulator/DropSpenserHandler.h
@@ -18,6 +18,22 @@ public:
{
}
+ inline static bool IsActivated(NIBBLETYPE a_Meta)
+ {
+ return (a_Meta & E_META_DROPSPENSER_ACTIVATED) != 0;
+ }
+ inline static NIBBLETYPE SetActivationState(NIBBLETYPE a_Meta, bool IsOn)
+ {
+ if (IsOn)
+ {
+ return a_Meta | E_META_DROPSPENSER_ACTIVATED; // set the bit
+ }
+ else
+ {
+ return a_Meta & ~E_META_DROPSPENSER_ACTIVATED; // clear the bit
+ }
+ }
+
virtual unsigned char GetPowerDeliveredToPosition(const Vector3i & a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, const Vector3i & a_QueryPosition, BLOCKTYPE a_QueryBlockType) override
{
UNUSED(a_Position);
@@ -39,8 +55,9 @@ public:
virtual cVector3iArray Update(const Vector3i & a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) override
{
// LOGD("Evaluating spencer the dropspenser (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
-
- if (a_PoweringData.PowerLevel > 0)
+ bool IsPoweredNow = (a_PoweringData.PowerLevel > 0);
+ bool WasPoweredPreviously = IsActivated(a_Meta);
+ if (IsPoweredNow && !WasPoweredPreviously)
{
class cSetPowerToDropSpenser :
public cDropSpenserCallback
@@ -56,6 +73,12 @@ public:
m_World.DoWithDropSpenserAt(a_Position.x, a_Position.y, a_Position.z, DrSpSP);
}
+ // Update the internal dropspenser state if necessary
+ if (IsPoweredNow != WasPoweredPreviously)
+ {
+ m_World.SetBlockMeta(a_Position, SetActivationState(a_Meta, IsPoweredNow));
+ }
+
return {};
}
diff --git a/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.cpp
index 9f8c0f39d..c7be24dc4 100644
--- a/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.cpp
+++ b/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.cpp
@@ -196,12 +196,12 @@ void cIncrementalRedstoneSimulator::Simulate(float a_dt)
cRedstoneHandler::PoweringData Power;
for (const auto & Location : CurrentHandler->GetValidSourcePositions(CurrentLocation, CurrentBlock, CurrentMeta))
{
- BLOCKTYPE PotentialBlock;
- NIBBLETYPE PotentialMeta;
- if ((Location.y < 0) || (Location.y > cChunkDef::Height))
+ if (!cChunk::IsValidHeight(Location.y))
{
continue;
}
+ BLOCKTYPE PotentialBlock;
+ NIBBLETYPE PotentialMeta;
m_World.GetBlockTypeMeta(Location.x, Location.y, Location.z, PotentialBlock, PotentialMeta);
auto PotentialSourceHandler = cIncrementalRedstoneSimulator::CreateComponent(m_World, PotentialBlock, &m_Data);