1
0
Fork 0

Merge pull request #3224 from QUSpilPrgm/master

Add an activation flag to the block metadata of droppers and dispensers
This commit is contained in:
Mattes D 2016-06-16 21:54:09 +02:00 committed by GitHub
commit ec998e821f
6 changed files with 42 additions and 9 deletions

View File

@ -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." },

View File

@ -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);

View File

@ -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;

View File

@ -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,

View File

@ -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 {};
}

View File

@ -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);