diff options
Diffstat (limited to '')
-rw-r--r-- | Server/Plugins/APIDump/APIDesc.lua | 8 | ||||
-rw-r--r-- | src/BlockEntities/DispenserEntity.cpp | 2 | ||||
-rw-r--r-- | src/BlockEntities/DropSpenserEntity.cpp | 6 | ||||
-rw-r--r-- | src/BlockID.h | 2 | ||||
-rw-r--r-- | src/Simulator/IncrementalRedstoneSimulator/DropSpenserHandler.h | 27 | ||||
-rw-r--r-- | src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.cpp | 6 |
6 files changed, 42 insertions, 9 deletions
diff --git a/Server/Plugins/APIDump/APIDesc.lua b/Server/Plugins/APIDump/APIDesc.lua index 16c39824b..fd8ef34d0 100644 --- a/Server/Plugins/APIDump/APIDesc.lua +++ b/Server/Plugins/APIDump/APIDesc.lua @@ -2990,6 +2990,14 @@ end DIG_STATUS_DROP_STACK = { Notes = "The player has dropped a full stack of items using the Drop Item key (default: Q) while holding down a specific modifier key (in windows, control)" }, DIG_STATUS_SHOOT_EAT = { Notes = "The player has finished shooting a bow or finished eating" }, DIG_STATUS_SWAP_ITEM_IN_HAND = { Notes = "The player has swapped their held item with the item in their offhand slot (1.9)" }, + E_META_DROPSPENSER_FACING_YM = { Notes = "A flag in the metadata of droppers and dispensers that indicates that the dropper or dispenser is looking in the negative Y direction." }, + E_META_DROPSPENSER_FACING_YP = { Notes = "A flag in the metadata of droppers and dispensers that indicates that the dropper or dispenser is looking in the positive Y direction." }, + E_META_DROPSPENSER_FACING_ZM = { Notes = "A flag in the metadata of droppers and dispensers that indicates that the dropper or dispenser is looking in the negative Z direction." }, + E_META_DROPSPENSER_FACING_ZP = { Notes = "A flag in the metadata of droppers and dispensers that indicates that the dropper or dispenser is looking in the positive Z direction." }, + E_META_DROPSPENSER_FACING_XM = { Notes = "A flag in the metadata of droppers and dispensers that indicates that the dropper or dispenser is looking in the negative X direction." }, + E_META_DROPSPENSER_FACING_XP = { Notes = "A flag in the metadata of droppers and dispensers that indicates that the dropper or dispenser is looking in the positive X direction." }, + E_META_DROPSPENSER_FACING_MASK = { Notes = "A mask that indicates the bits of the metadata that specify the facing of droppers and dispensers." }, + E_META_DROPSPENSER_ACTIVATED = { Notes = "A flag in the metadata of droppers and dispensers that indicates that the dropper or dispenser is currently activated. If this flag is set, the block must be unpowered first and powered again to shoot the next item." }, esBed = { Notes = "A bed explosion. The SourceData param is the {{Vector3i|position}} of the bed." }, esEnderCrystal = { Notes = "An ender crystal entity explosion. The SourceData param is the {{cEntity|ender crystal entity}} object." }, esGhastFireball = { Notes = "A ghast fireball explosion. The SourceData param is the {{cGhastFireballEntity|ghast fireball entity}} object." }, 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); |