1
0
Fork 0

Replace PowerData struct with PowerLevel

* We no longer need to track the powering block with the removal of SolidBlockHandler. PowerLevel is now just an unsigned char
This commit is contained in:
Tiger Wang 2020-08-20 20:04:28 +01:00
parent 03557e978e
commit d8c8d0124d
25 changed files with 171 additions and 189 deletions

View File

@ -9,7 +9,7 @@
namespace CommandBlockHandler
{
inline unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
inline PowerLevel GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
{
UNUSED(a_Chunk);
UNUSED(a_Position);
@ -20,12 +20,12 @@ namespace CommandBlockHandler
return 0;
}
inline void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData)
inline void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, const PowerLevel Power)
{
// LOGD("Evaluating commander the cmdblck (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
auto Previous = DataForChunk(a_Chunk).ExchangeUpdateOncePowerData(a_Position, a_PoweringData);
if ((Previous.PowerLevel != 0) || (a_PoweringData.PowerLevel == 0))
const auto Previous = DataForChunk(a_Chunk).ExchangeUpdateOncePowerData(a_Position, Power);
if ((Previous != 0) || (Power == 0))
{
// If we're already powered or received an update of no power, don't activate
return;

View File

@ -11,7 +11,7 @@ namespace DoorHandler
{
// "Doormammu, I've come to bargain"
inline unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
inline PowerLevel GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
{
UNUSED(a_Chunk);
UNUSED(a_Position);
@ -22,7 +22,7 @@ namespace DoorHandler
return 0;
}
inline void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData)
inline void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PowerLevel Power)
{
// LOGD("Evaluating dori the door (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
@ -37,10 +37,10 @@ namespace DoorHandler
RedstoneHandler::ForValidSourcePositions(a_Chunk, TopPosition, a_BlockType, a_Meta, Callback);
// Factor in what the upper half is getting:
a_PoweringData = std::max(a_PoweringData, Callback.Power);
Power = std::max(Power, Callback.Power);
cChunkInterface ChunkInterface(a_Chunk.GetWorld()->GetChunkMap());
const bool ShouldBeOpen = a_PoweringData.PowerLevel != 0;
const bool ShouldBeOpen = Power != 0;
const auto AbsolutePosition = cChunkDef::RelativeToAbsolute(a_Position, a_Chunk.GetPos());
const bool IsOpen = cBlockDoorHandler::IsOpen(ChunkInterface, AbsolutePosition);

View File

@ -26,7 +26,7 @@ namespace DropSpenserHandler
}
}
inline unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
inline PowerLevel GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
{
UNUSED(a_Chunk);
UNUSED(a_Position);
@ -37,11 +37,11 @@ namespace DropSpenserHandler
return 0;
}
inline void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData)
inline void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, const PowerLevel Power)
{
// LOGD("Evaluating spencer the dropspenser (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
const bool IsPoweredNow = (a_PoweringData.PowerLevel > 0);
const bool IsPoweredNow = (Power > 0);
const bool WasPoweredPreviously = IsActivated(a_Meta);
if (IsPoweredNow && !WasPoweredPreviously)

View File

@ -12,6 +12,7 @@
ForEachSourceCallback::ForEachSourceCallback(const cChunk & Chunk, const Vector3i Position, const BLOCKTYPE CurrentBlock) :
Power(0),
m_Chunk(Chunk),
m_Position(Position),
m_CurrentBlock(CurrentBlock)
@ -26,8 +27,13 @@ bool ForEachSourceCallback::ShouldQueryLinkedPosition(const Vector3i Location, c
{
switch (Block)
{
// Normally we don't ask solid blocks for power because they don't have any (store, dirt, etc.)
// However, these are mechanisms that are IsSolid, but still give power. Don't ignore them:
case E_BLOCK_BLOCK_OF_REDSTONE:
case E_BLOCK_OBSERVER:
case E_BLOCK_TRAPPED_CHEST: return false;
// If a mechanism asks for power from a block, redirect the query to linked positions if:
default: return cBlockInfo::IsSolid(Block);
}
}
@ -58,7 +64,13 @@ void ForEachSourceCallback::operator()(Vector3i Location)
}
else
{
Power = std::max(Power, QueryPower(*NeighbourChunk, Location, PotentialSourceBlock, NeighbourRelativeQueryPosition, m_CurrentBlock, false));
Power = std::max(
Power,
RedstoneHandler::GetPowerDeliveredToPosition(
*NeighbourChunk, Location, PotentialSourceBlock,
NeighbourRelativeQueryPosition, m_CurrentBlock, false
)
);
}
}
@ -66,26 +78,11 @@ void ForEachSourceCallback::operator()(Vector3i Location)
PoweringData ForEachSourceCallback::QueryPower(const cChunk & Chunk, const Vector3i SourcePosition, const BLOCKTYPE SourceBlock, const Vector3i QueryPosition, const BLOCKTYPE QueryBlock, const bool IsLinked)
PowerLevel ForEachSourceCallback::QueryLinkedPower(const cChunk & Chunk, const Vector3i QueryPosition, const BLOCKTYPE QueryBlock, const Vector3i SolidBlockPosition)
{
return
{
SourceBlock,
RedstoneHandler::GetPowerDeliveredToPosition(
Chunk, SourcePosition, SourceBlock,
QueryPosition, QueryBlock, IsLinked
)
};
}
PoweringData ForEachSourceCallback::QueryLinkedPower(const cChunk & Chunk, const Vector3i QueryPosition, const BLOCKTYPE QueryBlock, const Vector3i SolidBlockPosition)
{
PoweringData Power;
PowerLevel Power = 0;
// Loop through all linked powerable offsets in the direction requested:
for (const auto Offset : cSimulator::GetLinkedOffsets(SolidBlockPosition - QueryPosition))
{
auto SourcePosition = QueryPosition + Offset;
@ -100,8 +97,17 @@ PoweringData ForEachSourceCallback::QueryLinkedPower(const cChunk & Chunk, const
continue;
}
// Conduit block's position, relative to NeighbourChunk.
const auto NeighbourRelativeSolidBlockPosition = cIncrementalRedstoneSimulatorChunkData::RebaseRelativePosition(Chunk, *NeighbourChunk, SolidBlockPosition);
Power = std::max(Power, QueryPower(*NeighbourChunk, SourcePosition, NeighbourChunk->GetBlock(SourcePosition), NeighbourRelativeSolidBlockPosition, QueryBlock, true));
// Do a standard power query, but the requester's position is actually the solid block that will conduct power:
Power = std::max(
Power,
RedstoneHandler::GetPowerDeliveredToPosition(
*NeighbourChunk, SourcePosition, NeighbourChunk->GetBlock(SourcePosition),
NeighbourRelativeSolidBlockPosition, QueryBlock, true
)
);
}
return Power;

View File

@ -15,13 +15,11 @@ public:
/** Callback invoked for each potential source position of the redstone component. */
void operator()(Vector3i Location);
/** Asks a redstone component at the source position how much power it will deliver to the querying position. */
static PoweringData QueryPower(const cChunk & Chunk, Vector3i SourcePosition, BLOCKTYPE SourceBlock, Vector3i QueryPosition, BLOCKTYPE QueryBlock, bool IsLinked);
/** Asks redstone handlers adjacent to a solid block how much power they will deliver to the querying position, via the solid block.
Both QueryPosition and SolidBlockPosition are relative to Chunk. */
static PowerLevel QueryLinkedPower(const cChunk & Chunk, Vector3i QueryPosition, BLOCKTYPE QueryBlock, Vector3i SolidBlockPosition);
/** Asks redstone handlers adjacent to a solid block how much power they will deliver to the querying position, via the solid block. */
static PoweringData QueryLinkedPower(const cChunk & Chunk, Vector3i QueryPosition, BLOCKTYPE QueryBlock, Vector3i SolidBlockPosition);
PoweringData Power;
PowerLevel Power;
private:

View File

@ -9,7 +9,7 @@
namespace HopperHandler
{
inline unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
inline PowerLevel GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
{
UNUSED(a_Chunk);
UNUSED(a_Position);
@ -20,19 +20,19 @@ namespace HopperHandler
return 0;
}
inline void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData)
inline void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, const PowerLevel Power)
{
// LOGD("Evaluating holey the hopper (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
auto Previous = DataForChunk(a_Chunk).ExchangeUpdateOncePowerData(a_Position, a_PoweringData);
if (Previous.PowerLevel == a_PoweringData.PowerLevel)
const auto Previous = DataForChunk(a_Chunk).ExchangeUpdateOncePowerData(a_Position, Power);
if (Previous == Power)
{
return;
}
a_Chunk.DoWithHopperAt(a_Position, [a_PoweringData](cHopperEntity & a_Hopper)
a_Chunk.DoWithHopperAt(a_Position, [Power](cHopperEntity & a_Hopper)
{
a_Hopper.SetLocked(a_PoweringData.PowerLevel != 0);
a_Hopper.SetLocked(Power != 0);
return false;
});
}

View File

@ -9,7 +9,7 @@
namespace NoteBlockHandler
{
inline unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
inline PowerLevel GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
{
UNUSED(a_Chunk);
UNUSED(a_Position);
@ -20,12 +20,12 @@ namespace NoteBlockHandler
return 0;
}
inline void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData)
inline void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, const PowerLevel Power)
{
// LOGD("Evaluating sparky the magical note block (%d %d %d) %i", a_Position.x, a_Position.y, a_Position.z, a_PoweringData.PowerLevel);
// LOGD("Evaluating sparky the magical note block (%d %d %d) %i", a_Position.x, a_Position.y, a_Position.z, Power);
auto Previous = DataForChunk(a_Chunk).ExchangeUpdateOncePowerData(a_Position, a_PoweringData);
if ((Previous.PowerLevel != 0) || (a_PoweringData.PowerLevel == 0))
const auto Previous = DataForChunk(a_Chunk).ExchangeUpdateOncePowerData(a_Position, Power);
if ((Previous != 0) || (Power == 0))
{
// If we're already powered or received an update of no power, don't make a sound
return;

View File

@ -23,21 +23,36 @@ namespace ObserverHandler
return false;
}
// Cache the last seen block type and meta in the power data for this position
auto Observed = PoweringData(BlockType, BlockMeta);
auto Previous = a_Data.ExchangeUpdateOncePowerData(a_Position, Observed);
auto & ObserverCache = a_Data.ObserverCache;
const auto FindResult = ObserverCache.find(a_Position);
const auto Observed = std::make_pair(BlockType, BlockMeta);
if (FindResult == ObserverCache.end())
{
// Cache the last seen block for this position:
ObserverCache.emplace(a_Position, Observed);
// Definitely should signal update:
return true;
}
// The block this observer previously saw.
const auto Previous = FindResult->second;
// Update the last seen block:
FindResult->second = Observed;
// Determine if to signal an update based on the block previously observed changed
return (Previous.PoweringBlock != Observed.PoweringBlock) || (Previous.PowerLevel != Observed.PowerLevel);
return Previous != Observed;
}
inline unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
inline PowerLevel GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
{
const auto Meta = a_Chunk.GetMeta(a_Position);
return (IsOn(Meta) && (a_QueryPosition == (a_Position + cBlockObserverHandler::GetSignalOutputOffset(Meta)))) ? 15 : 0;
}
inline void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData)
inline void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, const PowerLevel Power)
{
// LOGD("Evaluating Lenny the observer (%i %i %i)", a_Position.x, a_Position.y, a_Position.z);

View File

@ -9,7 +9,7 @@
namespace PistonHandler
{
inline unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
inline PowerLevel GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
{
UNUSED(a_Chunk);
UNUSED(a_Position);
@ -20,11 +20,11 @@ namespace PistonHandler
return 0;
}
inline void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData)
inline void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, const PowerLevel Power)
{
// LOGD("Evaluating pisty the piston (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
const bool ShouldBeExtended = a_PoweringData.PowerLevel != 0;
const bool ShouldBeExtended = Power != 0;
if (ShouldBeExtended == cBlockPistonHandler::IsExtended(a_Meta))
{
return;

View File

@ -25,7 +25,7 @@ namespace PoweredRailHandler
}
}
inline unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
inline PowerLevel GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
{
UNUSED(a_QueryBlockType);
@ -33,13 +33,13 @@ namespace PoweredRailHandler
const auto Offset = GetPoweredRailAdjacentXZCoordinateOffset(Meta);
if (((Offset + a_Position) == a_QueryPosition) || ((-Offset + a_Position) == a_QueryPosition))
{
auto Power = DataForChunk(a_Chunk).GetCachedPowerData(a_Position).PowerLevel;
return (Power <= 7) ? 0 : --Power;
const auto Power = DataForChunk(a_Chunk).GetCachedPowerData(a_Position);
return (Power <= 7) ? 0 : (Power - 1);
}
return 0;
}
inline void Update(cChunk & a_Chunk, cChunk & CurrentlyTickingChunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData)
inline void Update(cChunk & a_Chunk, cChunk & CurrentlyTickingChunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, const PowerLevel Power)
{
// LOGD("Evaluating tracky the rail (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
@ -58,10 +58,10 @@ namespace PoweredRailHandler
case E_BLOCK_ACTIVATOR_RAIL:
case E_BLOCK_POWERED_RAIL:
{
auto Offset = GetPoweredRailAdjacentXZCoordinateOffset(a_Meta);
if (a_PoweringData != DataForChunk(a_Chunk).ExchangeUpdateOncePowerData(a_Position, a_PoweringData))
const auto Offset = GetPoweredRailAdjacentXZCoordinateOffset(a_Meta);
if (Power != DataForChunk(a_Chunk).ExchangeUpdateOncePowerData(a_Position, Power))
{
a_Chunk.SetMeta(a_Position, (a_PoweringData.PowerLevel == 0) ? (a_Meta & 0x07) : (a_Meta | 0x08));
a_Chunk.SetMeta(a_Position, (Power == 0) ? (a_Meta & 0x07) : (a_Meta | 0x08));
UpdateAdjustedRelative(a_Chunk, CurrentlyTickingChunk, a_Position, Offset);
UpdateAdjustedRelative(a_Chunk, CurrentlyTickingChunk, a_Position, -Offset);

View File

@ -91,7 +91,7 @@ namespace PressurePlateHandler
}
}
inline unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
inline PowerLevel GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
{
UNUSED(a_BlockType);
UNUSED(a_QueryPosition);
@ -99,10 +99,10 @@ namespace PressurePlateHandler
// Plates only link power blocks below
// Retrieve and return the cached power calculated by Update for performance:
return (IsLinked && (a_QueryPosition != (a_Position + OffsetYM))) ? 0 : DataForChunk(a_Chunk).GetCachedPowerData(a_Position).PowerLevel;
return (IsLinked && (a_QueryPosition != (a_Position + OffsetYM))) ? 0 : DataForChunk(a_Chunk).GetCachedPowerData(a_Position);
}
inline void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData)
inline void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, const PowerLevel Power)
{
// LOGD("Evaluating clicky the pressure plate (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
@ -110,13 +110,13 @@ namespace PressurePlateHandler
const auto PreviousPower = ChunkData.GetCachedPowerData(a_Position);
const auto Absolute = cChunkDef::RelativeToAbsolute(a_Position, a_Chunk.GetPos());
const auto Power = GetPowerLevel(a_Chunk, Absolute, a_BlockType); // Get the current power of the platey
const auto PowerLevel = GetPowerLevel(a_Chunk, Absolute, a_BlockType); // Get the current power of the platey
const auto DelayInfo = ChunkData.GetMechanismDelayInfo(a_Position);
// Resting state?
if (DelayInfo == nullptr)
{
if (Power == 0)
if (PowerLevel == 0)
{
// Nothing happened, back to rest
return;
@ -129,7 +129,7 @@ namespace PressurePlateHandler
a_Chunk.GetWorld()->BroadcastSoundEffect(GetClickOnSound(a_BlockType), Absolute, 0.5f, 0.6f);
// Update power
ChunkData.SetCachedPowerData(a_Position, PoweringData(a_BlockType, Power));
ChunkData.SetCachedPowerData(a_Position, PowerLevel);
// Immediately depress plate
a_Chunk.SetMeta(a_Position, E_META_PRESSURE_PLATE_DEPRESSED);
@ -148,7 +148,7 @@ namespace PressurePlateHandler
if (DelayTicks > 0)
{
// Nothing changes, if there is nothing on it anymore, because the state is locked.
if (Power == 0)
if (PowerLevel == 0)
{
return;
}
@ -161,10 +161,10 @@ namespace PressurePlateHandler
}
// Did the power level change and is still above zero?
if (Power != PreviousPower.PowerLevel)
if (PowerLevel != PreviousPower)
{
// Yes. Update power
ChunkData.SetCachedPowerData(a_Position, PoweringData(a_BlockType, Power));
ChunkData.SetCachedPowerData(a_Position, PowerLevel);
UpdateAdjustedRelatives(a_Chunk, CurrentlyTicking, a_Position, RelativeAdjacents);
}
@ -175,7 +175,7 @@ namespace PressurePlateHandler
if (HasExitedMinimumOnDelayPhase)
{
// Yep, initial delay elapsed. Has the player gotten off?
if (Power == 0)
if (PowerLevel == 0)
{
// Yes. Go into subsequent release delay, for a further 0.5 seconds
*DelayInfo = std::make_pair(5, false);
@ -183,10 +183,10 @@ namespace PressurePlateHandler
}
// Did the power level change and is still above zero?
if (Power != PreviousPower.PowerLevel)
if (PowerLevel != PreviousPower)
{
// Yes. Update power
ChunkData.SetCachedPowerData(a_Position, PoweringData(a_BlockType, Power));
ChunkData.SetCachedPowerData(a_Position, PowerLevel);
UpdateAdjustedRelatives(a_Chunk, CurrentlyTicking, a_Position, RelativeAdjacents);
}
@ -198,7 +198,7 @@ namespace PressurePlateHandler
ChunkData.m_MechanismDelays.erase(a_Position);
a_Chunk.GetWorld()->BroadcastSoundEffect(GetClickOffSound(a_BlockType), Absolute, 0.5f, 0.5f);
ChunkData.SetCachedPowerData(a_Position, PoweringData(a_BlockType, Power));
ChunkData.SetCachedPowerData(a_Position, PowerLevel);
a_Chunk.SetMeta(a_Position, E_META_PRESSURE_PLATE_RAISED);
UpdateAdjustedRelatives(a_Chunk, CurrentlyTicking, a_Position, RelativeAdjacents);

View File

@ -7,7 +7,7 @@
namespace RedstoneBlockHandler
{
inline unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
inline PowerLevel GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
{
UNUSED(a_Chunk);
UNUSED(a_Position);
@ -17,7 +17,7 @@ namespace RedstoneBlockHandler
return IsLinked ? 0 : 15;
}
inline void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData)
inline void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, const PowerLevel Power)
{
// LOGD("Evaluating crimson the redstone block (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
}

View File

@ -23,7 +23,7 @@ namespace RedstoneComparatorHandler
}
}
inline unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
inline PowerLevel GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
{
UNUSED(a_QueryPosition);
UNUSED(a_QueryBlockType);
@ -31,7 +31,7 @@ namespace RedstoneComparatorHandler
const auto Meta = a_Chunk.GetMeta(a_Position);
return (
(cBlockComparatorHandler::GetFrontCoordinate(a_Position, Meta & 0x3) == a_QueryPosition) ?
DataForChunk(a_Chunk).GetCachedPowerData(a_Position).PowerLevel : 0
DataForChunk(a_Chunk).GetCachedPowerData(a_Position) : 0
);
}
@ -79,9 +79,9 @@ namespace RedstoneComparatorHandler
);
}
inline void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData)
inline void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, const PowerLevel Power)
{
// Note that a_PoweringData here contains the maximum * side * power level, as specified by GetValidSourcePositions
// Note that Power here contains the maximum * side * power level, as specified by GetValidSourcePositions
// LOGD("Evaluating ALU the comparator (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
auto & Data = DataForChunk(a_Chunk);
@ -91,9 +91,9 @@ namespace RedstoneComparatorHandler
if (DelayInfo == nullptr)
{
const auto RearPower = GetPowerLevel(a_Chunk, a_Position, a_BlockType, a_Meta);
const auto FrontPower = GetFrontPowerLevel(a_Meta, a_PoweringData.PowerLevel, RearPower);
const auto FrontPower = GetFrontPowerLevel(a_Meta, Power, RearPower);
const auto PreviousFrontPower = Data.GetCachedPowerData(a_Position);
const bool ShouldUpdate = (FrontPower != PreviousFrontPower.PowerLevel); // "Business logic" (:P) - determined by side and rear power levels
const bool ShouldUpdate = (FrontPower != PreviousFrontPower); // "Business logic" (:P) - determined by side and rear power levels
if (ShouldUpdate)
{
@ -112,11 +112,11 @@ namespace RedstoneComparatorHandler
}
const auto RearPower = GetPowerLevel(a_Chunk, a_Position, a_BlockType, a_Meta);
const auto FrontPower = GetFrontPowerLevel(a_Meta, a_PoweringData.PowerLevel, RearPower);
const auto FrontPower = GetFrontPowerLevel(a_Meta, Power, RearPower);
const auto NewMeta = (FrontPower > 0) ? (a_Meta | 0x8) : (a_Meta & 0x7);
// Don't care about the previous power level so return value ignored
Data.ExchangeUpdateOncePowerData(a_Position, PoweringData(a_PoweringData.PoweringBlock, FrontPower));
Data.ExchangeUpdateOncePowerData(a_Position, FrontPower);
a_Chunk.SetMeta(a_Position, NewMeta);
Data.m_MechanismDelays.erase(a_Position);

View File

@ -87,7 +87,7 @@
namespace RedstoneHandler
{
unsigned char GetPowerDeliveredToPosition(const cChunk & Chunk, const Vector3i Position, const BLOCKTYPE BlockType, const Vector3i QueryPosition, const BLOCKTYPE QueryBlockType, const bool IsLinked)
PowerLevel GetPowerDeliveredToPosition(const cChunk & Chunk, const Vector3i Position, const BLOCKTYPE BlockType, const Vector3i QueryPosition, const BLOCKTYPE QueryBlockType, const bool IsLinked)
{
INVOKE_FOR_HANDLERS(GetPowerDeliveredToPosition(Chunk, Position, BlockType, QueryPosition, QueryBlockType, IsLinked));
@ -99,28 +99,16 @@ namespace RedstoneHandler
return 0;
}
void Update(cChunk & Chunk, cChunk & CurrentlyTicking, const Vector3i Position, const BLOCKTYPE BlockType, const NIBBLETYPE Meta, const PoweringData PoweringData)
void Update(cChunk & Chunk, cChunk & CurrentlyTicking, const Vector3i Position, const BLOCKTYPE BlockType, const NIBBLETYPE Meta, const PowerLevel PowerLevel)
{
INVOKE_FOR_HANDLERS(Update(Chunk, CurrentlyTicking, Position, BlockType, Meta, PoweringData));
INVOKE_FOR_HANDLERS(Update(Chunk, CurrentlyTicking, Position, BlockType, Meta, PowerLevel));
}
void ForValidSourcePositions(const cChunk & Chunk, const Vector3i Position, const BLOCKTYPE BlockType, const NIBBLETYPE Meta, ForEachSourceCallback & Callback)
{
INVOKE_FOR_HANDLERS(ForValidSourcePositions(Chunk, Position, BlockType, Meta, Callback));
}
void SetWireState(const cChunk & Chunk, const Vector3i Position)
{
RedstoneWireHandler::SetWireState(Chunk, Position);

View File

@ -8,11 +8,19 @@ class ForEachSourceCallback;
namespace RedstoneHandler
{
unsigned char GetPowerDeliveredToPosition(const cChunk & Chunk, Vector3i Position, BLOCKTYPE BlockType, Vector3i QueryPosition, BLOCKTYPE QueryBlockType, bool IsLinked);
/** Asks a redstone component at the source position how much power it will deliver to the querying position.
If IsLinked is true, QueryPosition should point to the intermediate conduit block.
The Position and QueryPosition are both relative to Chunk. */
PowerLevel GetPowerDeliveredToPosition(const cChunk & Chunk, Vector3i Position, BLOCKTYPE BlockType, Vector3i QueryPosition, BLOCKTYPE QueryBlockType, bool IsLinked);
void Update(cChunk & Chunk, cChunk & CurrentlyTicking, Vector3i Position, BLOCKTYPE BlockType, NIBBLETYPE Meta, PoweringData PoweringData);
/** Tells a redstone component at this position to update itself.
PowerLevel represents the maximum power level all of its source positions gave to it.
Position is relative to Chunk, but if the component needs to queue neighbour updates, they are queued to CurrentlyTicking. */
void Update(cChunk & Chunk, cChunk & CurrentlyTicking, Vector3i Position, BLOCKTYPE BlockType, NIBBLETYPE Meta, PowerLevel PowerLevel);
/** Invokes Callback for each position this component can accept power from. */
void ForValidSourcePositions(const cChunk & Chunk, Vector3i Position, BLOCKTYPE BlockType, NIBBLETYPE Meta, ForEachSourceCallback & Callback);
/** Temporary: compute and set the block state of a redstone wire. */
void SetWireState(const cChunk & Chunk, Vector3i Position);
}

View File

@ -12,16 +12,16 @@ namespace RedstoneLampHandler
return (a_BlockType == E_BLOCK_REDSTONE_LAMP_ON);
}
inline unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
inline PowerLevel GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
{
return 0;
}
inline void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData)
inline void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, const PowerLevel Power)
{
// LOGD("Evaluating lamp (%i %i %i)", a_Position.x, a_Position.y, a_Position.z);
if (a_PoweringData.PowerLevel > 0)
if (Power > 0)
{
if (!IsOn(a_BlockType))
{

View File

@ -81,7 +81,7 @@ namespace RedstoneRepeaterHandler
return Rhs.first && DoesLhsLockMe(a_Meta, Rhs.second);
}
inline unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
inline PowerLevel GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
{
if (!IsOn(a_BlockType))
{
@ -98,7 +98,7 @@ namespace RedstoneRepeaterHandler
return 0;
}
inline void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData)
inline void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, const PowerLevel Power)
{
// LOGD("Evaluating loopy the repeater (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
@ -118,7 +118,7 @@ namespace RedstoneRepeaterHandler
if (DelayInfo == nullptr)
{
bool ShouldBeOn = (a_PoweringData.PowerLevel != 0);
bool ShouldBeOn = (Power != 0);
if (ShouldBeOn != IsOn(a_BlockType))
{
Data.m_MechanismDelays[a_Position] = std::make_pair((((a_Meta & 0xC) >> 0x2) + 1), ShouldBeOn);
@ -143,7 +143,7 @@ namespace RedstoneRepeaterHandler
// While sleeping, we ignore any power changes and apply our saved ShouldBeOn when sleep expires
// Now, we need to recalculate to be aware of any new changes that may e.g. cause a new output change
// FastSetBlock doesn't wake simulators, so manually update ourselves:
Update(a_Chunk, CurrentlyTicking, a_Position, NewType, a_Meta, a_PoweringData);
Update(a_Chunk, CurrentlyTicking, a_Position, NewType, a_Meta, Power);
UpdateAdjustedRelative(a_Chunk, CurrentlyTicking, a_Position, cBlockRedstoneRepeaterHandler::GetFrontCoordinateOffset(a_Meta));
}

View File

@ -10,45 +10,7 @@
struct PoweringData
{
public:
PoweringData(BLOCKTYPE a_PoweringBlock, unsigned char a_PowerLevel) :
PoweringBlock(a_PoweringBlock),
PowerLevel(a_PowerLevel)
{
}
PoweringData(void) :
PoweringBlock(E_BLOCK_AIR),
PowerLevel(0)
{
}
BLOCKTYPE PoweringBlock;
unsigned char PowerLevel;
inline friend bool operator < (const PoweringData & Lhs, const PoweringData & Rhs)
{
return (
(Lhs.PowerLevel < Rhs.PowerLevel) ||
(
(Lhs.PowerLevel == Rhs.PowerLevel) &&
((Lhs.PoweringBlock == E_BLOCK_REDSTONE_WIRE) && (Rhs.PoweringBlock != E_BLOCK_REDSTONE_WIRE))
)
);
}
inline friend bool operator == (const PoweringData & Lhs, const PoweringData & Rhs)
{
return (Lhs.PowerLevel == Rhs.PowerLevel);
}
inline friend bool operator != (const PoweringData & Lhs, const PoweringData & Rhs)
{
return !operator ==(Lhs, Rhs);
}
};
using PowerLevel = unsigned char;
@ -68,15 +30,15 @@ public:
return m_ActiveBlocks;
}
const PoweringData GetCachedPowerData(const Vector3i Position) const
PowerLevel GetCachedPowerData(const Vector3i Position) const
{
auto Result = m_CachedPowerLevels.find(Position);
return (Result == m_CachedPowerLevels.end()) ? PoweringData() : Result->second;
return (Result == m_CachedPowerLevels.end()) ? 0 : Result->second;
}
void SetCachedPowerData(const Vector3i Position, PoweringData PoweringData)
void SetCachedPowerData(const Vector3i Position, const PowerLevel PowerLevel)
{
m_CachedPowerLevels[Position] = PoweringData;
m_CachedPowerLevels[Position] = PowerLevel;
}
std::pair<int, bool> * GetMechanismDelayInfo(const Vector3i Position)
@ -92,18 +54,21 @@ public:
m_MechanismDelays.erase(Position);
AlwaysTickedPositions.erase(Position);
WireStates.erase(Position);
ObserverCache.erase(Position);
}
PoweringData ExchangeUpdateOncePowerData(const Vector3i & a_Position, PoweringData a_PoweringData)
PowerLevel ExchangeUpdateOncePowerData(const Vector3i & a_Position, PowerLevel Power)
{
auto Result = m_CachedPowerLevels.find(a_Position);
if (Result == m_CachedPowerLevels.end())
{
m_CachedPowerLevels[a_Position] = a_PoweringData;
return PoweringData();
m_CachedPowerLevels[a_Position] = Power;
return 0;
}
std::swap(Result->second, a_PoweringData);
return a_PoweringData;
std::swap(Result->second, Power);
return Power;
}
/** Adjust From-relative coordinates into To-relative coordinates. */
@ -122,6 +87,9 @@ public:
std::unordered_set<Vector3i, VectorHasher<int>> AlwaysTickedPositions;
/** Structure storing an observer's last seen block. */
std::unordered_map<Vector3i, std::pair<BLOCKTYPE, NIBBLETYPE>, VectorHasher<int>> ObserverCache;
/** Structure storing position of mechanism + it's delay ticks (countdown) & if to power on. */
std::unordered_map<Vector3i, std::pair<int, bool>, VectorHasher<int>> m_MechanismDelays;
@ -131,8 +99,7 @@ private:
// TODO: map<Vector3i, int> -> Position of torch + it's heat level
std::unordered_map<Vector3i, PoweringData, VectorHasher<int>> m_CachedPowerLevels;
std::unordered_map<Vector3i, PowerLevel, VectorHasher<int>> m_CachedPowerLevels;
friend class cRedstoneHandlerFactory;
};

View File

@ -74,7 +74,7 @@ namespace RedstoneToggleHandler
}
}
inline unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
inline PowerLevel GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
{
UNUSED(a_QueryBlockType);
@ -89,7 +89,7 @@ namespace RedstoneToggleHandler
return GetPowerLevel(a_BlockType, Meta);
}
inline void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData)
inline void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, const PowerLevel Power)
{
// LOGD("Evaluating templatio<> the lever/button (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
}

View File

@ -29,7 +29,7 @@ namespace RedstoneTorchHandler
}
}
inline unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
inline PowerLevel GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
{
const auto QueryOffset = a_QueryPosition - a_Position;
@ -45,7 +45,7 @@ namespace RedstoneTorchHandler
return 15;
}
inline void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData)
inline void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, const PowerLevel Power)
{
// LOGD("Evaluating torchy the redstone torch (%i %i %i)", a_Position.x, a_Position.y, a_Position.z);
@ -54,7 +54,7 @@ namespace RedstoneTorchHandler
if (DelayInfo == nullptr)
{
const bool ShouldBeOn = (a_PoweringData.PowerLevel == 0);
const bool ShouldBeOn = (Power == 0);
if (ShouldBeOn != IsOn(a_BlockType))
{
Data.m_MechanismDelays[a_Position] = std::make_pair(1, ShouldBeOn);

View File

@ -189,7 +189,7 @@ namespace RedstoneWireHandler
DataForChunk(Chunk).WireStates[Position] = Block;
}
inline unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
inline PowerLevel GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
{
// Starts off as the wire's meta value, modified appropriately and returned
auto Power = a_Chunk.GetMeta(a_Position);
@ -253,16 +253,16 @@ namespace RedstoneWireHandler
return Power;
}
inline void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData)
inline void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, const PowerLevel Power)
{
// LOGD("Evaluating dusty the wire (%d %d %d) %i", a_Position.x, a_Position.y, a_Position.z, a_PoweringData.PowerLevel);
// LOGD("Evaluating dusty the wire (%d %d %d) %i", a_Position.x, a_Position.y, a_Position.z, Power);
if (a_Meta == a_PoweringData.PowerLevel)
if (a_Meta == Power)
{
return;
}
a_Chunk.SetMeta(a_Position, a_PoweringData.PowerLevel);
a_Chunk.SetMeta(a_Position, Power);
// Notify all positions, sans YP, to update:
for (const auto Offset : RelativeAdjacents)

View File

@ -7,7 +7,7 @@
namespace SmallGateHandler
{
inline unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
inline PowerLevel GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
{
UNUSED(a_Chunk);
UNUSED(a_Position);
@ -18,11 +18,11 @@ namespace SmallGateHandler
return 0;
}
inline void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData)
inline void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, const PowerLevel Power)
{
// LOGD("Evaluating gateydory the fence gate/trapdoor (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
const bool ShouldBeOpen = a_PoweringData.PowerLevel != 0;
const bool ShouldBeOpen = Power != 0;
const bool IsOpen = (a_Meta & 0x4) == 0x4;
if (ShouldBeOpen != IsOpen)

View File

@ -7,7 +7,7 @@
namespace TNTHandler
{
inline unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
inline PowerLevel GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
{
UNUSED(a_Chunk);
UNUSED(a_Position);
@ -18,10 +18,10 @@ namespace TNTHandler
return 0;
}
inline void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData)
inline void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, const PowerLevel Power)
{
// LOGD("Evaluating explodinator the trinitrotoluene (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
if (a_PoweringData.PowerLevel != 0)
if (Power != 0)
{
a_Chunk.SetBlock(a_Position, E_BLOCK_AIR, 0);
a_Chunk.GetWorld()->SpawnPrimedTNT(Vector3d(0.5, 0.5, 0.5) + cChunkDef::RelativeToAbsolute(a_Position, a_Chunk.GetPos())); // 80 ticks to boom

View File

@ -9,14 +9,14 @@
namespace TrappedChestHandler
{
inline unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
inline PowerLevel GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
{
UNUSED(a_BlockType);
UNUSED(a_QueryPosition);
UNUSED(a_QueryBlockType);
UNUSED(IsLinked);
return DataForChunk(a_Chunk).GetCachedPowerData(a_Position).PowerLevel;
return DataForChunk(a_Chunk).GetCachedPowerData(a_Position);
}
inline unsigned char GetPowerLevel(cChunk & a_Chunk, Vector3i a_Position)
@ -34,14 +34,14 @@ namespace TrappedChestHandler
return static_cast<unsigned char>(std::min(NumberOfPlayers, 15));
}
inline void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData)
inline void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, const PowerLevel Power)
{
// LOGD("Evaluating tricky the trapped chest (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
const auto Power = GetPowerLevel(a_Chunk, a_Position);
const auto PreviousPower = DataForChunk(a_Chunk).ExchangeUpdateOncePowerData(a_Position, PoweringData(a_BlockType, Power));
const auto PowerLevel = GetPowerLevel(a_Chunk, a_Position);
const auto PreviousPower = DataForChunk(a_Chunk).ExchangeUpdateOncePowerData(a_Position, PowerLevel);
if (Power != PreviousPower.PowerLevel)
if (PowerLevel != PreviousPower)
{
UpdateAdjustedRelatives(a_Chunk, CurrentlyTicking, a_Position, RelativeAdjacents);
}

View File

@ -60,7 +60,7 @@ namespace TripwireHookHandler
return 0;
}
inline unsigned char GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
inline PowerLevel GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
{
UNUSED(a_BlockType);
UNUSED(a_QueryBlockType);
@ -69,22 +69,22 @@ namespace TripwireHookHandler
return (GetPowerLevel(a_Chunk, a_Position, a_Chunk.GetMeta(a_Position)) == 15) ? 15 : 0;
}
inline void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData)
inline void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, const PowerLevel Power)
{
// LOGD("Evaluating hooky the tripwire hook (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
const auto Power = GetPowerLevel(a_Chunk, a_Position, a_Meta);
const auto PowerLevel = GetPowerLevel(a_Chunk, a_Position, a_Meta);
NIBBLETYPE Meta;
if (Power == 0)
if (PowerLevel == 0)
{
Meta = (a_Meta & 0x3);
}
else if (Power == 1)
else if (PowerLevel == 1)
{
// Connected but not activated, AND away the highest bit
Meta = (a_Meta & 0x7) | 0x4;
}
else if (Power == 15)
else if (PowerLevel == 15)
{
// Connected and activated, set the 3rd and 4th highest bits
Meta = (a_Meta | 0xC);