Always use relative coordinates in AddBlock
+ Pass block, use relatives * Fixes everything immediately converting abs back to rel and getting block, when these data were already available
This commit is contained in:
parent
99856df686
commit
225c2fa9f6
@ -58,10 +58,10 @@ void cBlockEntityWithItems::OnSlotChanged(cItemGrid * a_Grid, int a_SlotNum)
|
|||||||
auto & Simulator = *m_World->GetRedstoneSimulator();
|
auto & Simulator = *m_World->GetRedstoneSimulator();
|
||||||
|
|
||||||
// Notify comparators:
|
// Notify comparators:
|
||||||
Simulator.WakeUp(m_Pos + Vector3i(1, 0, 0), &a_Chunk);
|
m_World->WakeUpSimulators(m_Pos + Vector3i(1, 0, 0));
|
||||||
Simulator.WakeUp(m_Pos + Vector3i(-1, 0, 0), &a_Chunk);
|
m_World->WakeUpSimulators(m_Pos + Vector3i(-1, 0, 0));
|
||||||
Simulator.WakeUp(m_Pos + Vector3i(0, 0, 1), &a_Chunk);
|
m_World->WakeUpSimulators(m_Pos + Vector3i(0, 0, 1));
|
||||||
Simulator.WakeUp(m_Pos + Vector3i(0, 0, -1), &a_Chunk);
|
m_World->WakeUpSimulators(m_Pos + Vector3i(0, 0, -1));
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -216,3 +216,42 @@ bool cChestEntity::IsBlocked()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cChestEntity::OnSlotChanged(cItemGrid * a_Grid, int a_SlotNum)
|
||||||
|
{
|
||||||
|
ASSERT(a_Grid == &m_Contents);
|
||||||
|
|
||||||
|
if (m_World == nullptr)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Have cBlockEntityWithItems update redstone and try to broadcast our window:
|
||||||
|
Super::OnSlotChanged(a_Grid, a_SlotNum);
|
||||||
|
|
||||||
|
cWindow * Window = GetWindow();
|
||||||
|
if ((Window == nullptr) && (m_Neighbour != nullptr))
|
||||||
|
{
|
||||||
|
// Window was null, Super will have failed.
|
||||||
|
// Neighbour might own the window:
|
||||||
|
Window = m_Neighbour->GetWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Window != nullptr)
|
||||||
|
{
|
||||||
|
Window->BroadcastWholeWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_World->MarkChunkDirty(GetChunkX(), GetChunkZ());
|
||||||
|
m_World->DoWithChunkAt(m_Pos, [&](cChunk & a_Chunk)
|
||||||
|
{
|
||||||
|
auto & Simulator = *m_World->GetRedstoneSimulator();
|
||||||
|
|
||||||
|
// Notify comparators:
|
||||||
|
m_World->WakeUpSimulators(m_Pos + Vector3i(1, 0, 0));
|
||||||
|
m_World->WakeUpSimulators(m_Pos + Vector3i(-1, 0, 0));
|
||||||
|
m_World->WakeUpSimulators(m_Pos + Vector3i(0, 0, 1));
|
||||||
|
m_World->WakeUpSimulators(m_Pos + Vector3i(0, 0, -1));
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
@ -74,44 +74,7 @@ private:
|
|||||||
cChestEntity * m_Neighbour;
|
cChestEntity * m_Neighbour;
|
||||||
|
|
||||||
/** cItemGrid::cListener overrides: */
|
/** cItemGrid::cListener overrides: */
|
||||||
virtual void OnSlotChanged(cItemGrid * a_Grid, int a_SlotNum) override
|
virtual void OnSlotChanged(cItemGrid * a_Grid, int a_SlotNum) override;
|
||||||
{
|
|
||||||
ASSERT(a_Grid == &m_Contents);
|
|
||||||
|
|
||||||
if (m_World == nullptr)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Have cBlockEntityWithItems update redstone and try to broadcast our window:
|
|
||||||
Super::OnSlotChanged(a_Grid, a_SlotNum);
|
|
||||||
|
|
||||||
cWindow * Window = GetWindow();
|
|
||||||
if ((Window == nullptr) && (m_Neighbour != nullptr))
|
|
||||||
{
|
|
||||||
// Window was null, Super will have failed.
|
|
||||||
// Neighbour might own the window:
|
|
||||||
Window = m_Neighbour->GetWindow();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Window != nullptr)
|
|
||||||
{
|
|
||||||
Window->BroadcastWholeWindow();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_World->MarkChunkDirty(GetChunkX(), GetChunkZ());
|
|
||||||
m_World->DoWithChunkAt(m_Pos, [&](cChunk & a_Chunk)
|
|
||||||
{
|
|
||||||
auto & Simulator = *m_World->GetRedstoneSimulator();
|
|
||||||
|
|
||||||
// Notify comparators:
|
|
||||||
Simulator.WakeUp(m_Pos + Vector3i(1, 0, 0), &a_Chunk);
|
|
||||||
Simulator.WakeUp(m_Pos + Vector3i(-1, 0, 0), &a_Chunk);
|
|
||||||
Simulator.WakeUp(m_Pos + Vector3i(0, 0, 1), &a_Chunk);
|
|
||||||
Simulator.WakeUp(m_Pos + Vector3i(0, 0, -1), &a_Chunk);
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
} ; // tolua_export
|
} ; // tolua_export
|
||||||
|
|
||||||
|
@ -196,8 +196,7 @@ public:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto absPos = a_Chunk.RelativeToAbsolute(a_RelPos);
|
a_Chunk.GetWorld()->GetSimulatorManager()->WakeUp(a_Chunk, a_RelPos);
|
||||||
a_Chunk.GetWorld()->GetSimulatorManager()->WakeUp(absPos, &a_Chunk);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1241,40 +1241,12 @@ void cChunk::WakeUpSimulators(void)
|
|||||||
|
|
||||||
for (size_t BlockIdx = 0; BlockIdx != cChunkData::SectionBlockCount; ++BlockIdx)
|
for (size_t BlockIdx = 0; BlockIdx != cChunkData::SectionBlockCount; ++BlockIdx)
|
||||||
{
|
{
|
||||||
auto BlockType = Section->m_BlockTypes[BlockIdx];
|
const auto BlockType = Section->m_BlockTypes[BlockIdx];
|
||||||
|
const auto Position = IndexToCoordinate(BlockIdx);
|
||||||
|
|
||||||
// Defer calculation until it's actually needed
|
RedstoneSimulator->AddBlock(*this, Position, BlockType);
|
||||||
auto WorldPos = [&]
|
WaterSimulator->AddBlock(*this, Position, BlockType);
|
||||||
{
|
LavaSimulator->AddBlock(*this, Position, BlockType);
|
||||||
auto RelPos = IndexToCoordinate(BlockIdx);
|
|
||||||
RelPos.y += static_cast<int>(SectionIdx * cChunkData::SectionHeight);
|
|
||||||
return RelativeToAbsolute(RelPos);
|
|
||||||
};
|
|
||||||
|
|
||||||
// The redstone sim takes multiple blocks, use the inbuilt checker
|
|
||||||
if (RedstoneSimulator->IsAllowedBlock(BlockType))
|
|
||||||
{
|
|
||||||
RedstoneSimulator->AddBlock(WorldPos(), this);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (BlockType)
|
|
||||||
{
|
|
||||||
case E_BLOCK_WATER:
|
|
||||||
{
|
|
||||||
WaterSimulator->AddBlock(WorldPos(), this);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case E_BLOCK_LAVA:
|
|
||||||
{
|
|
||||||
LavaSimulator->AddBlock(WorldPos(), this);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} // switch (BlockType)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1316,7 +1288,7 @@ void cChunk::SetBlock(Vector3i a_RelPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_Blo
|
|||||||
|
|
||||||
// TODO: use relative coordinates, cChunk reference
|
// TODO: use relative coordinates, cChunk reference
|
||||||
// Wake up the simulators for this block:
|
// Wake up the simulators for this block:
|
||||||
GetWorld()->GetSimulatorManager()->WakeUp(RelativeToAbsolute(a_RelPos), this);
|
GetWorld()->GetSimulatorManager()->WakeUp(*this, a_RelPos);
|
||||||
|
|
||||||
// If there was a block entity, remove it:
|
// If there was a block entity, remove it:
|
||||||
cBlockEntity * BlockEntity = GetBlockEntityRel(a_RelPos);
|
cBlockEntity * BlockEntity = GetBlockEntityRel(a_RelPos);
|
||||||
|
@ -227,7 +227,8 @@ void cChunkMap::WakeUpSimulators(Vector3i a_Block)
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_World->GetSimulatorManager()->WakeUp(a_Block, Chunk);
|
|
||||||
|
m_World->GetSimulatorManager()->WakeUp(*Chunk, cChunkDef::AbsoluteToRelative(a_Block, Chunk->GetPos()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -644,7 +645,6 @@ void cChunkMap::SetBlock(Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE
|
|||||||
BlockHandler(blockType)->OnBroken(ChunkInterface, *m_World, a_BlockPos, blockType, blockMeta);
|
BlockHandler(blockType)->OnBroken(ChunkInterface, *m_World, a_BlockPos, blockType, blockMeta);
|
||||||
|
|
||||||
chunk->SetBlock(relPos, a_BlockType, a_BlockMeta);
|
chunk->SetBlock(relPos, a_BlockType, a_BlockMeta);
|
||||||
m_World->GetSimulatorManager()->WakeUp(a_BlockPos, chunk);
|
|
||||||
BlockHandler(a_BlockType)->OnPlaced(ChunkInterface, *m_World, a_BlockPos, a_BlockType, a_BlockMeta);
|
BlockHandler(a_BlockType)->OnPlaced(ChunkInterface, *m_World, a_BlockPos, a_BlockType, a_BlockMeta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -867,7 +867,6 @@ bool cChunkMap::DigBlock(Vector3i a_BlockPos)
|
|||||||
}
|
}
|
||||||
|
|
||||||
destChunk->SetBlock(relPos, E_BLOCK_AIR, 0);
|
destChunk->SetBlock(relPos, E_BLOCK_AIR, 0);
|
||||||
m_World->GetSimulatorManager()->WakeUp(a_BlockPos, destChunk);
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -78,27 +78,15 @@ cDelayedFluidSimulator::cDelayedFluidSimulator(cWorld & a_World, BLOCKTYPE a_Flu
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cDelayedFluidSimulator::AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block)
|
void cDelayedFluidSimulator::WakeUp(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block)
|
||||||
{
|
{
|
||||||
int RelX = a_Block.x - a_Chunk->GetPosX() * cChunkDef::Width;
|
if (!cChunkDef::IsValidHeight(a_Position.y))
|
||||||
int RelZ = a_Block.z - a_Chunk->GetPosZ() * cChunkDef::Width;
|
|
||||||
BLOCKTYPE BlockType = a_Chunk->GetBlock(RelX, a_Block.y, RelZ);
|
|
||||||
if (BlockType != m_FluidBlock)
|
|
||||||
{
|
{
|
||||||
|
// Not inside the world (may happen when rclk with a full bucket - the client sends Y = -1)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ChunkDataRaw = (m_FluidBlock == E_BLOCK_WATER) ? a_Chunk->GetWaterSimulatorData() : a_Chunk->GetLavaSimulatorData();
|
Super::WakeUp(a_Chunk, a_Position, a_Block);
|
||||||
cDelayedFluidSimulatorChunkData * ChunkData = static_cast<cDelayedFluidSimulatorChunkData *>(ChunkDataRaw);
|
|
||||||
cDelayedFluidSimulatorChunkData::cSlot & Slot = ChunkData->m_Slots[m_AddSlotNum];
|
|
||||||
|
|
||||||
// Add, if not already present:
|
|
||||||
if (!Slot.Add(RelX, a_Block.y, RelZ))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
++m_TotalBlocks;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -146,13 +134,22 @@ void cDelayedFluidSimulator::SimulateChunk(std::chrono::milliseconds a_Dt, int a
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cDelayedFluidSimulator::WakeUp(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block)
|
void cDelayedFluidSimulator::AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block)
|
||||||
{
|
{
|
||||||
if (!cChunkDef::IsValidHeight(a_Position.y))
|
if (a_Block != m_FluidBlock)
|
||||||
{
|
{
|
||||||
// Not inside the world (may happen when rclk with a full bucket - the client sends Y = -1)
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Super::WakeUp(a_Chunk, a_Position, a_Block);
|
auto ChunkDataRaw = (m_FluidBlock == E_BLOCK_WATER) ? a_Chunk.GetWaterSimulatorData() : a_Chunk.GetLavaSimulatorData();
|
||||||
|
cDelayedFluidSimulatorChunkData * ChunkData = static_cast<cDelayedFluidSimulatorChunkData *>(ChunkDataRaw);
|
||||||
|
cDelayedFluidSimulatorChunkData::cSlot & Slot = ChunkData->m_Slots[m_AddSlotNum];
|
||||||
|
|
||||||
|
// Add, if not already present:
|
||||||
|
if (!Slot.Add(a_Position.x, a_Position.y, a_Position.z))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
++m_TotalBlocks;
|
||||||
}
|
}
|
||||||
|
@ -54,15 +54,15 @@ public:
|
|||||||
|
|
||||||
cDelayedFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid, int a_TickDelay);
|
cDelayedFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid, int a_TickDelay);
|
||||||
|
|
||||||
// cSimulator overrides:
|
|
||||||
virtual void WakeUp(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override;
|
virtual void WakeUp(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override;
|
||||||
virtual void AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override;
|
|
||||||
virtual void Simulate(float a_Dt) override;
|
|
||||||
virtual void SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override;
|
|
||||||
virtual cFluidSimulatorData * CreateChunkData(void) override { return new cDelayedFluidSimulatorChunkData(m_TickDelay); }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
virtual void Simulate(float a_Dt) override;
|
||||||
|
virtual void SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override;
|
||||||
|
virtual void AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override;
|
||||||
|
virtual cFluidSimulatorData * CreateChunkData(void) override { return new cDelayedFluidSimulatorChunkData(m_TickDelay); }
|
||||||
|
|
||||||
int m_TickDelay; // Count of the m_Slots array in each ChunkData
|
int m_TickDelay; // Count of the m_Slots array in each ChunkData
|
||||||
int m_AddSlotNum; // Index into m_Slots[] where to add new blocks in each ChunkData
|
int m_AddSlotNum; // Index into m_Slots[] where to add new blocks in each ChunkData
|
||||||
int m_SimSlotNum; // Index into m_Slots[] where to simulate blocks in each ChunkData
|
int m_SimSlotNum; // Index into m_Slots[] where to simulate blocks in each ChunkData
|
||||||
|
@ -79,14 +79,6 @@ cFireSimulator::cFireSimulator(cWorld & a_World, cIniFile & a_IniFile) :
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
cFireSimulator::~cFireSimulator()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cFireSimulator::SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk)
|
void cFireSimulator::SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk)
|
||||||
{
|
{
|
||||||
cCoordWithIntList & Data = a_Chunk->GetFireSimulatorData();
|
cCoordWithIntList & Data = a_Chunk->GetFireSimulatorData();
|
||||||
@ -241,28 +233,21 @@ bool cFireSimulator::DoesBurnForever(BLOCKTYPE a_BlockType)
|
|||||||
|
|
||||||
void cFireSimulator::AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block)
|
void cFireSimulator::AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block)
|
||||||
{
|
{
|
||||||
if ((a_Chunk == nullptr) || !a_Chunk->IsValid())
|
if (!IsAllowedBlock(a_Block))
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto RelPos = cChunkDef::AbsoluteToRelative(a_Block, a_Chunk->GetPos());
|
|
||||||
BLOCKTYPE BlockType = a_Chunk->GetBlock(RelPos);
|
|
||||||
if (!IsAllowedBlock(BlockType))
|
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for duplicates:
|
// Check for duplicates:
|
||||||
cFireSimulatorChunkData & ChunkData = a_Chunk->GetFireSimulatorData();
|
cFireSimulatorChunkData & ChunkData = a_Chunk.GetFireSimulatorData();
|
||||||
for (cCoordWithIntList::iterator itr = ChunkData.begin(), end = ChunkData.end(); itr != end; ++itr)
|
for (cCoordWithIntList::iterator itr = ChunkData.begin(), end = ChunkData.end(); itr != end; ++itr)
|
||||||
{
|
{
|
||||||
const Vector3i ItrPos{itr->x, itr->y, itr->z};
|
const Vector3i ItrPos{itr->x, itr->y, itr->z};
|
||||||
if (ItrPos == RelPos)
|
if (ItrPos == a_Position)
|
||||||
{
|
{
|
||||||
// Block already present, check if burn step should decrease
|
// Block already present, check if burn step should decrease
|
||||||
// This means if fuel is removed, then the fire burns out sooner
|
// This means if fuel is removed, then the fire burns out sooner
|
||||||
const auto NewBurnStep = GetBurnStepTime(a_Chunk, RelPos);
|
const auto NewBurnStep = GetBurnStepTime(&a_Chunk, a_Position);
|
||||||
if (itr->Data > NewBurnStep)
|
if (itr->Data > NewBurnStep)
|
||||||
{
|
{
|
||||||
FIRE_FLOG("FS: Block lost its fuel at {0}", a_Block);
|
FIRE_FLOG("FS: Block lost its fuel at {0}", a_Block);
|
||||||
@ -274,7 +259,7 @@ void cFireSimulator::AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a
|
|||||||
} // for itr - ChunkData[]
|
} // for itr - ChunkData[]
|
||||||
|
|
||||||
FIRE_FLOG("FS: Adding block {0}", a_Block);
|
FIRE_FLOG("FS: Adding block {0}", a_Block);
|
||||||
ChunkData.push_back(cCoordWithInt(RelPos.x, RelPos.y, RelPos.z, 100));
|
ChunkData.push_back(cCoordWithInt(a_Position.x, a_Position.y, a_Position.z, 100));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,18 +19,19 @@ class cFireSimulator :
|
|||||||
public cSimulator
|
public cSimulator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
cFireSimulator(cWorld & a_World, cIniFile & a_IniFile);
|
cFireSimulator(cWorld & a_World, cIniFile & a_IniFile);
|
||||||
virtual ~cFireSimulator() override;
|
|
||||||
|
|
||||||
virtual void Simulate(float a_Dt) override { UNUSED(a_Dt);} // not used
|
|
||||||
virtual void SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override;
|
|
||||||
|
|
||||||
virtual bool IsAllowedBlock(BLOCKTYPE a_BlockType) override;
|
|
||||||
|
|
||||||
static bool IsFuel (BLOCKTYPE a_BlockType);
|
static bool IsFuel (BLOCKTYPE a_BlockType);
|
||||||
static bool DoesBurnForever(BLOCKTYPE a_BlockType);
|
static bool DoesBurnForever(BLOCKTYPE a_BlockType);
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
|
|
||||||
|
virtual void Simulate(float a_Dt) override { UNUSED(a_Dt);} // not used
|
||||||
|
virtual void SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override;
|
||||||
|
|
||||||
|
static bool IsAllowedBlock(BLOCKTYPE a_BlockType);
|
||||||
|
|
||||||
/** Time (in msec) that a fire block takes to burn with a fuel block into the next step */
|
/** Time (in msec) that a fire block takes to burn with a fuel block into the next step */
|
||||||
unsigned m_BurnStepTimeFuel;
|
unsigned m_BurnStepTimeFuel;
|
||||||
|
|
||||||
|
@ -309,7 +309,7 @@ void cFloodyFluidSimulator::SpreadToNeighbor(cChunk * a_NearChunk, int a_RelX, i
|
|||||||
// Spread:
|
// Spread:
|
||||||
FLUID_FLOG(" Spreading to {0} with meta {1}", absPos, a_NewMeta);
|
FLUID_FLOG(" Spreading to {0} with meta {1}", absPos, a_NewMeta);
|
||||||
a_NearChunk->SetBlock(relPos, m_FluidBlock, a_NewMeta);
|
a_NearChunk->SetBlock(relPos, m_FluidBlock, a_NewMeta);
|
||||||
m_World.GetSimulatorManager()->WakeUp(absPos, a_NearChunk);
|
m_World.GetSimulatorManager()->WakeUp(*a_NearChunk, relPos);
|
||||||
|
|
||||||
HardenBlock(a_NearChunk, relPos, m_FluidBlock, a_NewMeta);
|
HardenBlock(a_NearChunk, relPos, m_FluidBlock, a_NewMeta);
|
||||||
}
|
}
|
||||||
|
@ -43,14 +43,11 @@ public:
|
|||||||
|
|
||||||
cFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid);
|
cFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid);
|
||||||
|
|
||||||
// cSimulator overrides:
|
|
||||||
virtual bool IsAllowedBlock(BLOCKTYPE a_BlockType) override;
|
|
||||||
|
|
||||||
/** Returns a unit vector in the direction the fluid is flowing or a zero-vector if not flowing. */
|
/** Returns a unit vector in the direction the fluid is flowing or a zero-vector if not flowing. */
|
||||||
virtual Vector3f GetFlowingDirection(int a_X, int a_Y, int a_Z);
|
virtual Vector3f GetFlowingDirection(int a_X, int a_Y, int a_Z);
|
||||||
|
|
||||||
/** Creates a ChunkData object for the simulator to use. The simulator returns the correct object type. */
|
/** Creates a ChunkData object for the simulator to use. The simulator returns the correct object type. */
|
||||||
virtual cFluidSimulatorData * CreateChunkData(void) { return nullptr; }
|
virtual cFluidSimulatorData * CreateChunkData(void) = 0;
|
||||||
|
|
||||||
bool IsFluidBlock (BLOCKTYPE a_BlockType) const { return (a_BlockType == m_FluidBlock); }
|
bool IsFluidBlock (BLOCKTYPE a_BlockType) const { return (a_BlockType == m_FluidBlock); }
|
||||||
bool IsStationaryFluidBlock(BLOCKTYPE a_BlockType) const { return (a_BlockType == m_StationaryFluidBlock); }
|
bool IsStationaryFluidBlock(BLOCKTYPE a_BlockType) const { return (a_BlockType == m_StationaryFluidBlock); }
|
||||||
@ -65,6 +62,9 @@ public:
|
|||||||
bool IsHigherMeta(NIBBLETYPE a_Meta1, NIBBLETYPE a_Meta2);
|
bool IsHigherMeta(NIBBLETYPE a_Meta1, NIBBLETYPE a_Meta2);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
bool IsAllowedBlock(BLOCKTYPE a_BlockType);
|
||||||
|
|
||||||
BLOCKTYPE m_FluidBlock; // The fluid block type that needs simulating
|
BLOCKTYPE m_FluidBlock; // The fluid block type that needs simulating
|
||||||
BLOCKTYPE m_StationaryFluidBlock; // The fluid block type that indicates no simulation is needed
|
BLOCKTYPE m_StationaryFluidBlock; // The fluid block type that indicates no simulation is needed
|
||||||
};
|
};
|
||||||
|
@ -273,26 +273,18 @@ void cIncrementalRedstoneSimulator::ProcessWorkItem(cChunk & Chunk, cChunk & Tic
|
|||||||
|
|
||||||
void cIncrementalRedstoneSimulator::AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block)
|
void cIncrementalRedstoneSimulator::AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block)
|
||||||
{
|
{
|
||||||
// Can't inspect block, ignore:
|
auto & ChunkData = *static_cast<cIncrementalRedstoneSimulatorChunkData *>(a_Chunk.GetRedstoneSimulatorData());
|
||||||
if ((a_Chunk == nullptr) || !a_Chunk->IsValid())
|
|
||||||
|
if (!IsRedstone(a_Block))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto & ChunkData = *static_cast<cIncrementalRedstoneSimulatorChunkData *>(a_Chunk->GetRedstoneSimulatorData());
|
if (IsAlwaysTicked(a_Block))
|
||||||
const auto Relative = cChunkDef::AbsoluteToRelative(a_Block, a_Chunk->GetPos());
|
|
||||||
const auto CurrentBlock = a_Chunk->GetBlock(Relative);
|
|
||||||
|
|
||||||
if (!IsRedstone(CurrentBlock))
|
|
||||||
{
|
{
|
||||||
return;
|
ChunkData.AlwaysTickedPositions.emplace(a_Position);
|
||||||
}
|
|
||||||
|
|
||||||
if (IsAlwaysTicked(CurrentBlock))
|
|
||||||
{
|
|
||||||
ChunkData.AlwaysTickedPositions.emplace(Relative);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Always update redstone devices:
|
// Always update redstone devices:
|
||||||
ChunkData.WakeUp(Relative);
|
ChunkData.WakeUp(a_Position);
|
||||||
}
|
}
|
||||||
|
@ -21,26 +21,7 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
static const cRedstoneHandler * GetComponentHandler(BLOCKTYPE a_BlockType);
|
||||||
|
|
||||||
virtual void WakeUp(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override;
|
|
||||||
|
|
||||||
virtual void Simulate(float Dt) override {};
|
|
||||||
virtual void SimulateChunk(std::chrono::milliseconds Dt, int ChunkX, int ChunkZ, cChunk * Chunk) override;
|
|
||||||
|
|
||||||
void ProcessWorkItem(cChunk & Chunk, cChunk & TickingSource, const Vector3i Position);
|
|
||||||
|
|
||||||
virtual cIncrementalRedstoneSimulatorChunkData * CreateChunkData() override
|
|
||||||
{
|
|
||||||
return new cIncrementalRedstoneSimulatorChunkData;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool IsAllowedBlock(BLOCKTYPE a_BlockType) override
|
|
||||||
{
|
|
||||||
return IsRedstone(a_BlockType);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override;
|
|
||||||
|
|
||||||
/** Returns if a block is a mechanism (something that accepts power and does something)
|
/** Returns if a block is a mechanism (something that accepts power and does something)
|
||||||
Used by torches to determine if they will power a block */
|
Used by torches to determine if they will power a block */
|
||||||
@ -164,7 +145,20 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const cRedstoneHandler * GetComponentHandler(BLOCKTYPE a_BlockType);
|
private:
|
||||||
|
|
||||||
|
virtual void WakeUp(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override;
|
||||||
|
virtual void Simulate(float Dt) override {};
|
||||||
|
virtual void SimulateChunk(std::chrono::milliseconds Dt, int ChunkX, int ChunkZ, cChunk * Chunk) override;
|
||||||
|
|
||||||
|
void ProcessWorkItem(cChunk & Chunk, cChunk & TickingSource, const Vector3i Position);
|
||||||
|
|
||||||
|
virtual cIncrementalRedstoneSimulatorChunkData * CreateChunkData() override
|
||||||
|
{
|
||||||
|
return new cIncrementalRedstoneSimulatorChunkData;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -22,18 +22,17 @@ class cNoopFluidSimulator:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
cNoopFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid):
|
using Super::cFluidSimulator;
|
||||||
Super(a_World, a_Fluid, a_StationaryFluid)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// cSimulator overrides:
|
private:
|
||||||
|
|
||||||
|
virtual void Simulate(float a_Dt) override { UNUSED(a_Dt);}
|
||||||
virtual void AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override
|
virtual void AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override
|
||||||
{
|
{
|
||||||
UNUSED(a_Block);
|
UNUSED(a_Block);
|
||||||
UNUSED(a_Chunk);
|
UNUSED(a_Chunk);
|
||||||
}
|
}
|
||||||
virtual void Simulate(float a_Dt) override { UNUSED(a_Dt);}
|
virtual cFluidSimulatorData * CreateChunkData(void) override { return nullptr; }
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
@ -20,14 +20,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void Simulate(float a_Dt) override { UNUSED(a_Dt);} // not used
|
virtual void Simulate(float a_Dt) override { UNUSED(a_Dt);} // not used
|
||||||
virtual void SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override
|
|
||||||
{
|
|
||||||
UNUSED(a_Dt);
|
|
||||||
UNUSED(a_ChunkX);
|
|
||||||
UNUSED(a_ChunkZ);
|
|
||||||
UNUSED(a_Chunk);
|
|
||||||
}
|
|
||||||
virtual bool IsAllowedBlock( BLOCKTYPE a_BlockType) override { return false; }
|
|
||||||
virtual void AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override
|
virtual void AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override
|
||||||
{
|
{
|
||||||
UNUSED(a_Block);
|
UNUSED(a_Block);
|
||||||
|
@ -99,29 +99,23 @@ bool cSandSimulator::IsAllowedBlock(BLOCKTYPE a_BlockType)
|
|||||||
|
|
||||||
void cSandSimulator::AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block)
|
void cSandSimulator::AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block)
|
||||||
{
|
{
|
||||||
if ((a_Chunk == nullptr) || !a_Chunk->IsValid())
|
if (!IsAllowedBlock(a_Block))
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int RelX = a_Block.x - a_Chunk->GetPosX() * cChunkDef::Width;
|
|
||||||
int RelZ = a_Block.z - a_Chunk->GetPosZ() * cChunkDef::Width;
|
|
||||||
if (!IsAllowedBlock(a_Chunk->GetBlock(RelX, a_Block.y, RelZ)))
|
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for duplicates:
|
// Check for duplicates:
|
||||||
cSandSimulatorChunkData & ChunkData = a_Chunk->GetSandSimulatorData();
|
cSandSimulatorChunkData & ChunkData = a_Chunk.GetSandSimulatorData();
|
||||||
for (cSandSimulatorChunkData::iterator itr = ChunkData.begin(); itr != ChunkData.end(); ++itr)
|
for (cSandSimulatorChunkData::iterator itr = ChunkData.begin(); itr != ChunkData.end(); ++itr)
|
||||||
{
|
{
|
||||||
if ((itr->x == RelX) && (itr->y == a_Block.y) && (itr->z == RelZ))
|
if ((itr->x == a_Position.x) && (itr->y == a_Position.y) && (itr->z == a_Position.z))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_TotalBlocks += 1;
|
m_TotalBlocks += 1;
|
||||||
ChunkData.push_back(cCoordWithInt(RelX, a_Block.y, RelZ));
|
ChunkData.push_back(cCoordWithInt(a_Position.x, a_Position.y, a_Position.z));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,11 +30,6 @@ public:
|
|||||||
|
|
||||||
cSandSimulator(cWorld & a_World, cIniFile & a_IniFile);
|
cSandSimulator(cWorld & a_World, cIniFile & a_IniFile);
|
||||||
|
|
||||||
// cSimulator overrides:
|
|
||||||
virtual void Simulate(float a_Dt) override { UNUSED(a_Dt);} // not used
|
|
||||||
virtual void SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override;
|
|
||||||
virtual bool IsAllowedBlock(BLOCKTYPE a_BlockType) override;
|
|
||||||
|
|
||||||
/** Returns true if a falling-able block can start falling through the specified block type */
|
/** Returns true if a falling-able block can start falling through the specified block type */
|
||||||
static bool CanStartFallingThrough(BLOCKTYPE a_BlockType);
|
static bool CanStartFallingThrough(BLOCKTYPE a_BlockType);
|
||||||
|
|
||||||
@ -56,7 +51,12 @@ public:
|
|||||||
BLOCKTYPE a_FallingBlockType, NIBBLETYPE a_FallingBlockMeta
|
BLOCKTYPE a_FallingBlockType, NIBBLETYPE a_FallingBlockMeta
|
||||||
);
|
);
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
|
|
||||||
|
virtual void Simulate(float a_Dt) override { UNUSED(a_Dt);} // not used
|
||||||
|
virtual void SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override;
|
||||||
|
|
||||||
|
static bool IsAllowedBlock(BLOCKTYPE a_BlockType);
|
||||||
|
|
||||||
bool m_IsInstantFall; // If set to true, blocks don't fall using cFallingBlock entity, but instantly instead
|
bool m_IsInstantFall; // If set to true, blocks don't fall using cFallingBlock entity, but instantly instead
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
|
|
||||||
friend class cChunk; // Calls AddBlock() in its WakeUpSimulators() function, to speed things up
|
friend class cChunk; // Calls AddBlock() in its WakeUpSimulators() function, to speed things up
|
||||||
|
friend class cSimulatorManager; // Class reponsible for dispatching calls to the various slave Simulators
|
||||||
|
|
||||||
virtual void Simulate(float a_Dt) = 0;
|
virtual void Simulate(float a_Dt) = 0;
|
||||||
virtual void SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk)
|
virtual void SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk)
|
||||||
@ -42,11 +43,8 @@ protected:
|
|||||||
UNUSED(a_Chunk);
|
UNUSED(a_Chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns true if the specified block type is "interesting" for this simulator. */
|
|
||||||
virtual bool IsAllowedBlock(BLOCKTYPE a_BlockType) = 0;
|
|
||||||
|
|
||||||
/** Called to simulate a new block. Unlike WakeUp this function will perform minimal checking.
|
/** Called to simulate a new block. Unlike WakeUp this function will perform minimal checking.
|
||||||
It queues the block to be simulated as fast as possible, only making sure that the block type IsAllowedBlock. */
|
It queues the block to be simulated as fast as possible, suitable for area wakeups. */
|
||||||
virtual void AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) = 0;
|
virtual void AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) = 0;
|
||||||
|
|
||||||
/** Called to simulate a single new block, typically as a result of a single block break or change.
|
/** Called to simulate a single new block, typically as a result of a single block break or change.
|
||||||
|
@ -13,32 +13,14 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
cVaporizeFluidSimulator::cVaporizeFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid) :
|
|
||||||
Super(a_World, a_Fluid, a_StationaryFluid)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cVaporizeFluidSimulator::AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block)
|
void cVaporizeFluidSimulator::AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block)
|
||||||
{
|
{
|
||||||
if (a_Chunk == nullptr)
|
if ((a_Block == m_FluidBlock) || (a_Block == m_StationaryFluidBlock))
|
||||||
{
|
{
|
||||||
return;
|
a_Chunk.FastSetBlock(a_Position, E_BLOCK_AIR, 0);
|
||||||
}
|
|
||||||
auto relPos = cChunkDef::AbsoluteToRelative(a_Block);
|
|
||||||
auto blockType = a_Chunk->GetBlock(relPos);
|
|
||||||
if (
|
|
||||||
(blockType == m_FluidBlock) ||
|
|
||||||
(blockType == m_StationaryFluidBlock)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
a_Chunk->SetBlock(relPos, E_BLOCK_AIR, 0);
|
|
||||||
World::GetBroadcastInterface(m_World).BroadcastSoundEffect(
|
World::GetBroadcastInterface(m_World).BroadcastSoundEffect(
|
||||||
"block.fire.extinguish",
|
"block.fire.extinguish",
|
||||||
Vector3d(a_Block),
|
Vector3d(a_Position),
|
||||||
1.0f,
|
1.0f,
|
||||||
0.6f
|
0.6f
|
||||||
);
|
);
|
||||||
|
@ -23,11 +23,13 @@ class cVaporizeFluidSimulator:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
cVaporizeFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid);
|
using Super::cFluidSimulator;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
// cSimulator overrides:
|
|
||||||
virtual void AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override;
|
|
||||||
virtual void Simulate(float a_Dt) override;
|
virtual void Simulate(float a_Dt) override;
|
||||||
|
virtual void AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override;
|
||||||
|
virtual cFluidSimulatorData * CreateChunkData(void) override { return nullptr; }
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user