Improved link power behaviour
This commit is contained in:
parent
bef7cce5ed
commit
6a831c0b6f
@ -713,7 +713,7 @@ void cIncrementalRedstoneSimulator::PowerBorderingWires(std::vector<std::pair<Ve
|
|||||||
RC.a_PowerLevel = a_MyPower - 1;
|
RC.a_PowerLevel = a_MyPower - 1;
|
||||||
|
|
||||||
auto & PoweredBlocks = static_cast<cIncrementalRedstoneSimulatorChunkData *>(a_NeighbourChunk->GetRedstoneSimulatorData())->m_PoweredBlocks; // We need to insert the value into the chunk who owns the block position
|
auto & PoweredBlocks = static_cast<cIncrementalRedstoneSimulatorChunkData *>(a_NeighbourChunk->GetRedstoneSimulatorData())->m_PoweredBlocks; // We need to insert the value into the chunk who owns the block position
|
||||||
auto Position = std::find_if(PoweredBlocks.begin(), PoweredBlocks.end(), [RC](const sPoweredBlocks & itr) { return itr.a_BlockPos == RC.a_BlockPos && itr.a_SourcePos == RC.a_SourcePos; });
|
auto Position = std::find_if(PoweredBlocks.begin(), PoweredBlocks.end(), [RC](const sPoweredBlocks & itr) { return ((itr.a_BlockPos == RC.a_BlockPos) && (itr.a_SourcePos == RC.a_SourcePos)); });
|
||||||
if (Position != PoweredBlocks.end())
|
if (Position != PoweredBlocks.end())
|
||||||
{
|
{
|
||||||
Position->a_PowerLevel = RC.a_PowerLevel;
|
Position->a_PowerLevel = RC.a_PowerLevel;
|
||||||
@ -819,19 +819,50 @@ void cIncrementalRedstoneSimulator::HandleRedstoneRepeater(int a_RelBlockX, int
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// Create a variable holding my meta to avoid multiple lookups.
|
// Create a variable holding my meta to avoid multiple lookups.
|
||||||
NIBBLETYPE a_Meta = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ);
|
NIBBLETYPE Meta = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ);
|
||||||
bool IsOn = (a_MyState == E_BLOCK_REDSTONE_REPEATER_ON);
|
bool IsOn = (a_MyState == E_BLOCK_REDSTONE_REPEATER_ON);
|
||||||
|
|
||||||
if (!IsRepeaterLocked(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta)) // If we're locked, change nothing. Otherwise:
|
if (!IsRepeaterLocked(a_RelBlockX, a_RelBlockY, a_RelBlockZ, Meta)) // If we're locked, change nothing. Otherwise:
|
||||||
{
|
{
|
||||||
bool IsSelfPowered = IsRepeaterPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta);
|
bool IsSelfPowered = IsRepeaterPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, Meta);
|
||||||
if (IsSelfPowered && !IsOn) // Queue a power change if powered, but not on and not locked.
|
if (IsSelfPowered && !IsOn) // Queue a power change if powered, but not on and not locked.
|
||||||
{
|
{
|
||||||
QueueRepeaterPowerChange(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta, true);
|
QueueRepeaterPowerChange(a_RelBlockX, a_RelBlockY, a_RelBlockZ, Meta, true);
|
||||||
}
|
}
|
||||||
else if (!IsSelfPowered && IsOn) // Queue a power change if unpowered, on, and not locked.
|
else if (!IsSelfPowered && IsOn) // Queue a power change if unpowered, on, and not locked.
|
||||||
{
|
{
|
||||||
QueueRepeaterPowerChange(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta, false);
|
QueueRepeaterPowerChange(a_RelBlockX, a_RelBlockY, a_RelBlockZ, Meta, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsOn)
|
||||||
|
{
|
||||||
|
switch (Meta & 0x3) // We only want the direction (bottom) bits
|
||||||
|
{
|
||||||
|
case 0x0:
|
||||||
|
{
|
||||||
|
SetBlockPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ);
|
||||||
|
SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_ZM);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x1:
|
||||||
|
{
|
||||||
|
SetBlockPowered(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ);
|
||||||
|
SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_XP);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x2:
|
||||||
|
{
|
||||||
|
SetBlockPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ);
|
||||||
|
SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_ZP);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x3:
|
||||||
|
{
|
||||||
|
SetBlockPowered(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ);
|
||||||
|
SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_XM);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -855,34 +886,6 @@ void cIncrementalRedstoneSimulator::HandleRedstoneRepeaterDelays()
|
|||||||
{
|
{
|
||||||
m_Chunk->SetBlock(itr->a_RelBlockPos, E_BLOCK_REDSTONE_REPEATER_ON, Meta);
|
m_Chunk->SetBlock(itr->a_RelBlockPos, E_BLOCK_REDSTONE_REPEATER_ON, Meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (Meta & 0x3) // We only want the direction (bottom) bits
|
|
||||||
{
|
|
||||||
case 0x0:
|
|
||||||
{
|
|
||||||
SetBlockPowered(RelBlockX, RelBlockY, RelBlockZ - 1, RelBlockX, RelBlockY, RelBlockZ);
|
|
||||||
SetDirectionLinkedPowered(RelBlockX, RelBlockY, RelBlockZ, BLOCK_FACE_ZM);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 0x1:
|
|
||||||
{
|
|
||||||
SetBlockPowered(RelBlockX + 1, RelBlockY, RelBlockZ, RelBlockX, RelBlockY, RelBlockZ);
|
|
||||||
SetDirectionLinkedPowered(RelBlockX, RelBlockY, RelBlockZ, BLOCK_FACE_XP);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 0x2:
|
|
||||||
{
|
|
||||||
SetBlockPowered(RelBlockX, RelBlockY, RelBlockZ + 1, RelBlockX, RelBlockY, RelBlockZ);
|
|
||||||
SetDirectionLinkedPowered(RelBlockX, RelBlockY, RelBlockZ, BLOCK_FACE_ZP);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 0x3:
|
|
||||||
{
|
|
||||||
SetBlockPowered(RelBlockX - 1, RelBlockY, RelBlockZ, RelBlockX, RelBlockY, RelBlockZ);
|
|
||||||
SetDirectionLinkedPowered(RelBlockX, RelBlockY, RelBlockZ, BLOCK_FACE_XM);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (Block != E_BLOCK_REDSTONE_REPEATER_OFF)
|
else if (Block != E_BLOCK_REDSTONE_REPEATER_OFF)
|
||||||
{
|
{
|
||||||
@ -2027,16 +2030,16 @@ void cIncrementalRedstoneSimulator::SetBlockPowered(Vector3i a_RelBlockPosition,
|
|||||||
a_RelSourcePosition.z += (m_Chunk->GetPosZ() - Neighbour->GetPosZ()) * cChunkDef::Width;
|
a_RelSourcePosition.z += (m_Chunk->GetPosZ() - Neighbour->GetPosZ()) * cChunkDef::Width;
|
||||||
|
|
||||||
auto & Powered = static_cast<cIncrementalRedstoneSimulatorChunkData *>(Neighbour->GetRedstoneSimulatorData())->m_PoweredBlocks; // We need to insert the value into the chunk who owns the block position
|
auto & Powered = static_cast<cIncrementalRedstoneSimulatorChunkData *>(Neighbour->GetRedstoneSimulatorData())->m_PoweredBlocks; // We need to insert the value into the chunk who owns the block position
|
||||||
for (auto itr = Powered.begin(); itr != Powered.end(); ++itr)
|
for (auto & itr : Powered)
|
||||||
{
|
{
|
||||||
if ((itr->a_BlockPos == a_RelBlockPosition) && (itr->a_SourcePos == a_RelSourcePosition))
|
if ((itr.a_BlockPos == a_RelBlockPosition) && (itr.a_SourcePos == a_RelSourcePosition))
|
||||||
{
|
{
|
||||||
if (itr->a_PowerLevel != a_PowerLevel)
|
if (itr.a_PowerLevel != a_PowerLevel)
|
||||||
{
|
{
|
||||||
// Update power level, don't add a new listing
|
// Update power level, don't add a new listing
|
||||||
Neighbour->SetIsRedstoneDirty(true);
|
Neighbour->SetIsRedstoneDirty(true);
|
||||||
m_Chunk->SetIsRedstoneDirty(true);
|
m_Chunk->SetIsRedstoneDirty(true);
|
||||||
itr->a_PowerLevel = a_PowerLevel;
|
itr.a_PowerLevel = a_PowerLevel;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2068,11 +2071,14 @@ void cIncrementalRedstoneSimulator::SetBlockLinkedPowered(
|
|||||||
}
|
}
|
||||||
|
|
||||||
cChunk * Neighbour = m_Chunk->GetRelNeighborChunkAdjustCoords(a_RelBlockX, a_RelBlockZ);
|
cChunk * Neighbour = m_Chunk->GetRelNeighborChunkAdjustCoords(a_RelBlockX, a_RelBlockZ);
|
||||||
m_Chunk->GetRelNeighborChunkAdjustCoords(a_RelMiddleX, a_RelMiddleZ);
|
|
||||||
if ((Neighbour == nullptr) || !Neighbour->IsValid())
|
if ((Neighbour == nullptr) || !Neighbour->IsValid())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
a_RelMiddleX += (m_Chunk->GetPosX() - Neighbour->GetPosX()) * cChunkDef::Width;
|
||||||
|
a_RelMiddleZ += (m_Chunk->GetPosZ() - Neighbour->GetPosZ()) * cChunkDef::Width;
|
||||||
|
a_RelSourceX += (m_Chunk->GetPosX() - Neighbour->GetPosX()) * cChunkDef::Width;
|
||||||
|
a_RelSourceZ += (m_Chunk->GetPosZ() - Neighbour->GetPosZ()) * cChunkDef::Width;
|
||||||
|
|
||||||
auto & Linked = static_cast<cIncrementalRedstoneSimulatorChunkData *>(Neighbour->GetRedstoneSimulatorData())->m_LinkedBlocks;
|
auto & Linked = static_cast<cIncrementalRedstoneSimulatorChunkData *>(Neighbour->GetRedstoneSimulatorData())->m_LinkedBlocks;
|
||||||
for (auto & itr : Linked) // Check linked powered list
|
for (auto & itr : Linked) // Check linked powered list
|
||||||
@ -2083,8 +2089,13 @@ void cIncrementalRedstoneSimulator::SetBlockLinkedPowered(
|
|||||||
itr.a_SourcePos.Equals(Vector3i(a_RelSourceX, a_RelSourceY, a_RelSourceZ))
|
itr.a_SourcePos.Equals(Vector3i(a_RelSourceX, a_RelSourceY, a_RelSourceZ))
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// Check for duplicates, update power level, don't add a new listing
|
if (itr.a_PowerLevel != a_PowerLevel)
|
||||||
itr.a_PowerLevel = a_PowerLevel;
|
{
|
||||||
|
// Update power level, don't add a new listing
|
||||||
|
Neighbour->SetIsRedstoneDirty(true);
|
||||||
|
m_Chunk->SetIsRedstoneDirty(true);
|
||||||
|
itr.a_PowerLevel = a_PowerLevel;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2175,6 +2186,12 @@ void cIncrementalRedstoneSimulator::SetSourceUnpowered(int a_RelSourceX, int a_R
|
|||||||
|
|
||||||
auto UnpoweringFunction = [&BlocksPotentiallyUnpowered](cChunk * a_Chunk, const Vector3i & a_RelSource)
|
auto UnpoweringFunction = [&BlocksPotentiallyUnpowered](cChunk * a_Chunk, const Vector3i & a_RelSource)
|
||||||
{
|
{
|
||||||
|
BLOCKTYPE RepeaterType;
|
||||||
|
if (a_Chunk->UnboundedRelGetBlockType(a_RelSource.x, a_RelSource.y, a_RelSource.z, RepeaterType) && (RepeaterType == E_BLOCK_REDSTONE_REPEATER_ON))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
auto Data = static_cast<cIncrementalRedstoneSimulatorChunkData *>(a_Chunk->GetRedstoneSimulatorData());
|
auto Data = static_cast<cIncrementalRedstoneSimulatorChunkData *>(a_Chunk->GetRedstoneSimulatorData());
|
||||||
Data->m_PoweredBlocks.erase(std::remove_if(Data->m_PoweredBlocks.begin(), Data->m_PoweredBlocks.end(), [&BlocksPotentiallyUnpowered, a_Chunk, a_RelSource](const sPoweredBlocks & itr)
|
Data->m_PoweredBlocks.erase(std::remove_if(Data->m_PoweredBlocks.begin(), Data->m_PoweredBlocks.end(), [&BlocksPotentiallyUnpowered, a_Chunk, a_RelSource](const sPoweredBlocks & itr)
|
||||||
{
|
{
|
||||||
@ -2183,42 +2200,12 @@ void cIncrementalRedstoneSimulator::SetSourceUnpowered(int a_RelSourceX, int a_R
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto & BoundaryChunk : GetAdjacentChunks(a_RelSource, a_Chunk))
|
|
||||||
{
|
|
||||||
if (BoundaryChunk != a_Chunk)
|
|
||||||
{
|
|
||||||
Vector3i ChunkAdjustedSource = a_RelSource;
|
|
||||||
ChunkAdjustedSource.x += (a_Chunk->GetPosX() - BoundaryChunk->GetPosX()) * cChunkDef::Width;
|
|
||||||
ChunkAdjustedSource.z += (a_Chunk->GetPosZ() - BoundaryChunk->GetPosZ()) * cChunkDef::Width;
|
|
||||||
|
|
||||||
auto BoundaryData = (cIncrementalRedstoneSimulator::cIncrementalRedstoneSimulatorChunkData *)BoundaryChunk->GetRedstoneSimulatorData();
|
|
||||||
BoundaryData->m_PoweredBlocks.erase(std::remove_if(BoundaryData->m_PoweredBlocks.begin(), BoundaryData->m_PoweredBlocks.end(), [&BlocksPotentiallyUnpowered, BoundaryChunk, ChunkAdjustedSource](const sPoweredBlocks & itr)
|
|
||||||
{
|
|
||||||
if (itr.a_SourcePos != ChunkAdjustedSource)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
BlocksPotentiallyUnpowered.emplace_back(std::make_pair(itr.a_BlockPos, BoundaryChunk));
|
|
||||||
BoundaryChunk->SetIsRedstoneDirty(true);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
), BoundaryData->m_PoweredBlocks.end());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BLOCKTYPE RepeaterType;
|
|
||||||
if (a_Chunk->UnboundedRelGetBlockType(a_RelSource.x, a_RelSource.y, a_RelSource.z, RepeaterType) && (RepeaterType == E_BLOCK_REDSTONE_REPEATER_ON))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
BlocksPotentiallyUnpowered.emplace_back(std::make_pair(itr.a_BlockPos, a_Chunk));
|
BlocksPotentiallyUnpowered.emplace_back(std::make_pair(itr.a_BlockPos, a_Chunk));
|
||||||
a_Chunk->SetIsRedstoneDirty(true);
|
a_Chunk->SetIsRedstoneDirty(true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
), Data->m_PoweredBlocks.end());
|
), Data->m_PoweredBlocks.end());
|
||||||
|
|
||||||
Data->m_LinkedBlocks.erase(std::remove_if(Data->m_LinkedBlocks.begin(), Data->m_LinkedBlocks.end(), [&BlocksPotentiallyUnpowered, a_Chunk, a_RelSource](const sLinkedPoweredBlocks & itr)
|
Data->m_LinkedBlocks.erase(std::remove_if(Data->m_LinkedBlocks.begin(), Data->m_LinkedBlocks.end(), [&BlocksPotentiallyUnpowered, a_Chunk, a_RelSource](const sLinkedPoweredBlocks & itr)
|
||||||
{
|
{
|
||||||
if (itr.a_SourcePos != a_RelSource)
|
if (itr.a_SourcePos != a_RelSource)
|
||||||
@ -2226,41 +2213,27 @@ void cIncrementalRedstoneSimulator::SetSourceUnpowered(int a_RelSourceX, int a_R
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto & BoundaryChunk : GetAdjacentChunks(a_RelSource, a_Chunk))
|
|
||||||
{
|
|
||||||
if (BoundaryChunk != a_Chunk)
|
|
||||||
{
|
|
||||||
Vector3i ChunkAdjustedSource = a_RelSource;
|
|
||||||
ChunkAdjustedSource.x += (a_Chunk->GetPosX() - BoundaryChunk->GetPosX()) * cChunkDef::Width;
|
|
||||||
ChunkAdjustedSource.z += (a_Chunk->GetPosZ() - BoundaryChunk->GetPosZ()) * cChunkDef::Width;
|
|
||||||
|
|
||||||
auto BoundaryData = (cIncrementalRedstoneSimulator::cIncrementalRedstoneSimulatorChunkData *)BoundaryChunk->GetRedstoneSimulatorData();
|
|
||||||
BoundaryData->m_LinkedBlocks.erase(std::remove_if(BoundaryData->m_LinkedBlocks.begin(), BoundaryData->m_LinkedBlocks.end(), [&BlocksPotentiallyUnpowered, BoundaryChunk, ChunkAdjustedSource](const sLinkedPoweredBlocks & itr)
|
|
||||||
{
|
|
||||||
if (itr.a_SourcePos != ChunkAdjustedSource)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
BlocksPotentiallyUnpowered.emplace_back(std::make_pair(itr.a_BlockPos, BoundaryChunk));
|
|
||||||
BoundaryChunk->SetIsRedstoneDirty(true);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
), BoundaryData->m_LinkedBlocks.end());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BLOCKTYPE RepeaterType;
|
|
||||||
if (a_Chunk->UnboundedRelGetBlockType(a_RelSource.x, a_RelSource.y, a_RelSource.z, RepeaterType) && (RepeaterType == E_BLOCK_REDSTONE_REPEATER_ON))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
BlocksPotentiallyUnpowered.emplace_back(std::make_pair(itr.a_BlockPos, a_Chunk));
|
BlocksPotentiallyUnpowered.emplace_back(std::make_pair(itr.a_BlockPos, a_Chunk));
|
||||||
a_Chunk->SetIsRedstoneDirty(true);
|
a_Chunk->SetIsRedstoneDirty(true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
), Data->m_LinkedBlocks.end());
|
), Data->m_LinkedBlocks.end());
|
||||||
|
|
||||||
|
for (const auto & BoundaryChunk : GetAdjacentChunks(a_RelSource, a_Chunk))
|
||||||
|
{
|
||||||
|
auto BoundaryData = static_cast<cIncrementalRedstoneSimulatorChunkData *>(BoundaryChunk->GetRedstoneSimulatorData());
|
||||||
|
Vector3i ChunkAdjustedSource = a_RelSource;
|
||||||
|
ChunkAdjustedSource.x += (a_Chunk->GetPosX() - BoundaryChunk->GetPosX()) * cChunkDef::Width;
|
||||||
|
ChunkAdjustedSource.z += (a_Chunk->GetPosZ() - BoundaryChunk->GetPosZ()) * cChunkDef::Width;
|
||||||
|
|
||||||
|
if (
|
||||||
|
(std::find_if(BoundaryData->m_PoweredBlocks.begin(), BoundaryData->m_PoweredBlocks.end(), [ChunkAdjustedSource](const sPoweredBlocks & itr) { return (itr.a_SourcePos == ChunkAdjustedSource); }) != BoundaryData->m_PoweredBlocks.end()) ||
|
||||||
|
(std::find_if(BoundaryData->m_LinkedBlocks.begin(), BoundaryData->m_LinkedBlocks.end(), [ChunkAdjustedSource](const sLinkedPoweredBlocks & itr) { return (itr.a_SourcePos == ChunkAdjustedSource); }) != BoundaryData->m_LinkedBlocks.end())
|
||||||
|
)
|
||||||
|
{
|
||||||
|
BlocksPotentiallyUnpowered.emplace_back(std::make_pair(ChunkAdjustedSource, BoundaryChunk));
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
while (!BlocksPotentiallyUnpowered.empty())
|
while (!BlocksPotentiallyUnpowered.empty())
|
||||||
@ -2275,45 +2248,56 @@ void cIncrementalRedstoneSimulator::SetSourceUnpowered(int a_RelSourceX, int a_R
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cIncrementalRedstoneSimulator::SetInvalidMiddleBlock(int a_RelMiddleX, int a_RelMiddleY, int a_RelMiddleZ, cChunk * a_Chunk, bool a_IsFirstCall)
|
void cIncrementalRedstoneSimulator::SetInvalidMiddleBlock(int a_RelMiddleX, int a_RelMiddleY, int a_RelMiddleZ, cChunk * a_Chunk)
|
||||||
{
|
{
|
||||||
if (!a_IsFirstCall) // The neighbouring chunks passed when this parameter is false may be invalid
|
std::vector<std::pair<Vector3i, cChunk *>> BlocksPotentiallyUnpowered;
|
||||||
{
|
|
||||||
if ((a_Chunk == nullptr) || !a_Chunk->IsValid())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<Vector3i> BlocksPotentiallyUnpowered;
|
|
||||||
auto Data = static_cast<cIncrementalRedstoneSimulatorChunkData *>(a_Chunk->GetRedstoneSimulatorData());
|
auto Data = static_cast<cIncrementalRedstoneSimulatorChunkData *>(a_Chunk->GetRedstoneSimulatorData());
|
||||||
|
|
||||||
Data->m_LinkedBlocks.erase(std::remove_if(Data->m_LinkedBlocks.begin(), Data->m_LinkedBlocks.end(), [&BlocksPotentiallyUnpowered, a_Chunk, a_RelMiddleX, a_RelMiddleY, a_RelMiddleZ](const sLinkedPoweredBlocks & itr)
|
Data->m_LinkedBlocks.erase(std::remove_if(Data->m_LinkedBlocks.begin(), Data->m_LinkedBlocks.end(), [&BlocksPotentiallyUnpowered, a_Chunk, a_RelMiddleX, a_RelMiddleY, a_RelMiddleZ](const sLinkedPoweredBlocks & itr)
|
||||||
{
|
{
|
||||||
if (itr.a_MiddlePos.Equals(Vector3i(a_RelMiddleX, a_RelMiddleY, a_RelMiddleZ)))
|
if (!itr.a_MiddlePos.Equals(Vector3i(a_RelMiddleX, a_RelMiddleY, a_RelMiddleZ)))
|
||||||
{
|
{
|
||||||
BlocksPotentiallyUnpowered.emplace_back(itr.a_BlockPos);
|
return false;
|
||||||
a_Chunk->SetIsRedstoneDirty(true);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
|
for (const auto & BoundaryChunk : GetAdjacentChunks(Vector3i(a_RelMiddleX, a_RelMiddleY, a_RelMiddleZ), a_Chunk))
|
||||||
|
{
|
||||||
|
Vector3i ChunkAdjustedMiddlePos = Vector3i(a_RelMiddleX, a_RelMiddleY, a_RelMiddleZ);
|
||||||
|
ChunkAdjustedMiddlePos.x += (a_Chunk->GetPosX() - BoundaryChunk->GetPosX()) * cChunkDef::Width;
|
||||||
|
ChunkAdjustedMiddlePos.z += (a_Chunk->GetPosZ() - BoundaryChunk->GetPosZ()) * cChunkDef::Width;
|
||||||
|
|
||||||
|
auto BoundaryData = static_cast<cIncrementalRedstoneSimulatorChunkData *>(BoundaryChunk->GetRedstoneSimulatorData());
|
||||||
|
BoundaryData->m_LinkedBlocks.erase(std::remove_if(BoundaryData->m_LinkedBlocks.begin(), BoundaryData->m_LinkedBlocks.end(), [&BlocksPotentiallyUnpowered, BoundaryChunk, ChunkAdjustedMiddlePos](const sLinkedPoweredBlocks & itr)
|
||||||
|
{
|
||||||
|
if (itr.a_MiddlePos != ChunkAdjustedMiddlePos)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
BlocksPotentiallyUnpowered.emplace_back(std::make_pair(itr.a_BlockPos, BoundaryChunk));
|
||||||
|
BoundaryChunk->SetIsRedstoneDirty(true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
), BoundaryData->m_LinkedBlocks.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
BLOCKTYPE RepeaterType;
|
||||||
|
if (a_Chunk->UnboundedRelGetBlockType(a_RelMiddleX, a_RelMiddleY, a_RelMiddleZ, RepeaterType) && (RepeaterType == E_BLOCK_REDSTONE_REPEATER_ON))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
BlocksPotentiallyUnpowered.emplace_back(std::make_pair(itr.a_BlockPos, a_Chunk));
|
||||||
|
a_Chunk->SetIsRedstoneDirty(true);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
), Data->m_LinkedBlocks.end());
|
), Data->m_LinkedBlocks.end());
|
||||||
|
|
||||||
if (a_IsFirstCall && /*AreCoordsOnChunkBoundary(a_RelMiddleX, a_RelMiddleY, a_RelMiddleZ)*/1)
|
|
||||||
{
|
|
||||||
// +- 2 to accomodate linked powered blocks
|
|
||||||
SetInvalidMiddleBlock(a_RelMiddleX, a_RelMiddleY, a_RelMiddleZ, a_Chunk->GetRelNeighborChunk(a_RelMiddleX - 2, a_RelMiddleZ), false);
|
|
||||||
SetInvalidMiddleBlock(a_RelMiddleX, a_RelMiddleY, a_RelMiddleZ, a_Chunk->GetRelNeighborChunk(a_RelMiddleX + 2, a_RelMiddleZ), false);
|
|
||||||
SetInvalidMiddleBlock(a_RelMiddleX, a_RelMiddleY, a_RelMiddleZ, a_Chunk->GetRelNeighborChunk(a_RelMiddleX, a_RelMiddleZ - 2), false);
|
|
||||||
SetInvalidMiddleBlock(a_RelMiddleX, a_RelMiddleY, a_RelMiddleZ, a_Chunk->GetRelNeighborChunk(a_RelMiddleX, a_RelMiddleZ + 2), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto & itr : BlocksPotentiallyUnpowered)
|
for (const auto & itr : BlocksPotentiallyUnpowered)
|
||||||
{
|
{
|
||||||
if (!AreCoordsPowered(itr.x, itr.y, itr.z))
|
if (!AreCoordsPowered(itr.first.x, itr.first.y, itr.first.z))
|
||||||
{
|
{
|
||||||
SetSourceUnpowered(itr.x, itr.y, itr.z, a_Chunk->GetRelNeighborChunk(itr.x, itr.z));
|
SetSourceUnpowered(itr.first.x, itr.first.y, itr.first.z, itr.second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2346,19 +2330,19 @@ std::vector<cChunk *> cIncrementalRedstoneSimulator::GetAdjacentChunks(const Vec
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Are we on a chunk boundary? +- 2 because of LinkedPowered blocks
|
// Are we on a chunk boundary? +- 2 because of LinkedPowered blocks
|
||||||
if ((a_RelBlockPosition.x % cChunkDef::Width) <= 1)
|
if (a_RelBlockPosition.x <= 1)
|
||||||
{
|
{
|
||||||
CheckAndEmplace(a_Chunk->GetRelNeighborChunk(a_RelBlockPosition.x - 2, a_RelBlockPosition.z));
|
CheckAndEmplace(a_Chunk->GetRelNeighborChunk(a_RelBlockPosition.x - 2, a_RelBlockPosition.z));
|
||||||
}
|
}
|
||||||
if ((a_RelBlockPosition.x % cChunkDef::Width) >= 14)
|
if (a_RelBlockPosition.x >= 14)
|
||||||
{
|
{
|
||||||
CheckAndEmplace(a_Chunk->GetRelNeighborChunk(a_RelBlockPosition.x + 2, a_RelBlockPosition.z));
|
CheckAndEmplace(a_Chunk->GetRelNeighborChunk(a_RelBlockPosition.x + 2, a_RelBlockPosition.z));
|
||||||
}
|
}
|
||||||
if ((a_RelBlockPosition.z % cChunkDef::Width) <= 1)
|
if (a_RelBlockPosition.z <= 1)
|
||||||
{
|
{
|
||||||
CheckAndEmplace(a_Chunk->GetRelNeighborChunk(a_RelBlockPosition.x, a_RelBlockPosition.z - 2));
|
CheckAndEmplace(a_Chunk->GetRelNeighborChunk(a_RelBlockPosition.x, a_RelBlockPosition.z - 2));
|
||||||
}
|
}
|
||||||
if ((a_RelBlockPosition.z % cChunkDef::Width) >= 14)
|
if (a_RelBlockPosition.z >= 14)
|
||||||
{
|
{
|
||||||
CheckAndEmplace(a_Chunk->GetRelNeighborChunk(a_RelBlockPosition.x, a_RelBlockPosition.z + 2));
|
CheckAndEmplace(a_Chunk->GetRelNeighborChunk(a_RelBlockPosition.x, a_RelBlockPosition.z + 2));
|
||||||
}
|
}
|
||||||
|
@ -214,10 +214,10 @@ private:
|
|||||||
bool QueueRepeaterPowerChange(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta, bool ShouldPowerOn);
|
bool QueueRepeaterPowerChange(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta, bool ShouldPowerOn);
|
||||||
|
|
||||||
/** Removes a block from the Powered and LinkedPowered lists
|
/** Removes a block from the Powered and LinkedPowered lists
|
||||||
Used for variable sources such as tripwire hooks, daylight sensors, and trapped chests
|
Recursively removes all blocks powered by the given one
|
||||||
*/
|
*/
|
||||||
void SetSourceUnpowered(int a_RelSourceX, int a_RelSourceY, int a_RelSourceZ, cChunk * a_Chunk);
|
void SetSourceUnpowered(int a_RelSourceX, int a_RelSourceY, int a_RelSourceZ, cChunk * a_Chunk);
|
||||||
void SetInvalidMiddleBlock(int a_RelMiddleX, int a_RelMiddleY, int a_RelMiddleZ, cChunk * a_Chunk, bool a_IsFirstCall = true);
|
void SetInvalidMiddleBlock(int a_RelMiddleX, int a_RelMiddleY, int a_RelMiddleZ, cChunk * a_Chunk);
|
||||||
|
|
||||||
/** Returns if a coordinate is powered or linked powered */
|
/** Returns if a coordinate is powered or linked powered */
|
||||||
bool AreCoordsPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) { return AreCoordsDirectlyPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, m_Chunk) || AreCoordsLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, m_Chunk); }
|
bool AreCoordsPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) { return AreCoordsDirectlyPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, m_Chunk) || AreCoordsLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, m_Chunk); }
|
||||||
@ -414,35 +414,7 @@ private:
|
|||||||
|
|
||||||
inline static Vector3i AdjustRelativeCoords(const Vector3i & a_RelPosition)
|
inline static Vector3i AdjustRelativeCoords(const Vector3i & a_RelPosition)
|
||||||
{
|
{
|
||||||
if (
|
return Vector3i((a_RelPosition.x % cChunkDef::Width + cChunkDef::Width) % cChunkDef::Width, a_RelPosition.y, (a_RelPosition.z % cChunkDef::Width + cChunkDef::Width) % cChunkDef::Width);
|
||||||
(a_RelPosition.x >= 0) && (a_RelPosition.x < cChunkDef::Width) &&
|
|
||||||
(a_RelPosition.z >= 0) && (a_RelPosition.z < cChunkDef::Width)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return a_RelPosition;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3i RelPos = a_RelPosition;
|
|
||||||
|
|
||||||
// Request for a different chunk, calculate chunk offset:
|
|
||||||
while (RelPos.x >= cChunkDef::Width)
|
|
||||||
{
|
|
||||||
RelPos.x -= cChunkDef::Width;
|
|
||||||
}
|
|
||||||
while (RelPos.x < 0)
|
|
||||||
{
|
|
||||||
RelPos.x += cChunkDef::Width;
|
|
||||||
}
|
|
||||||
while (RelPos.z >= cChunkDef::Width)
|
|
||||||
{
|
|
||||||
RelPos.z -= cChunkDef::Width;
|
|
||||||
}
|
|
||||||
while (RelPos.z < 0)
|
|
||||||
{
|
|
||||||
RelPos.z += cChunkDef::Width;
|
|
||||||
}
|
|
||||||
|
|
||||||
return RelPos;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user