void cFireSimulator::SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) { cCoordWithIntList & Data = a_Chunk->GetFireSimulatorData(); int NumMSecs = static_cast<int>(a_Dt.count()); for (cCoordWithIntList::iterator itr = Data.begin(); itr != Data.end();) { int x = itr->x; int y = itr->y; int z = itr->z; BLOCKTYPE BlockType = a_Chunk->GetBlock(x, y, z); if (!IsAllowedBlock(BlockType)) { // The block is no longer eligible (not a fire block anymore; a player probably placed a block over the fire) FLOG("FS: Removing block {%d, %d, %d}", itr->x + a_ChunkX * cChunkDef::Width, itr->y, itr->z + a_ChunkZ * cChunkDef::Width ); itr = Data.erase(itr); continue; } // Try to spread the fire: TrySpreadFire(a_Chunk, itr->x, itr->y, itr->z); itr->Data -= NumMSecs; if (itr->Data >= 0) { // Not yet, wait for it longer ++itr; continue; } // Burn out the fire one step by increasing the meta: /* FLOG("FS: Fire at {%d, %d, %d} is stepping", itr->x + a_ChunkX * cChunkDef::Width, itr->y, itr->z + a_ChunkZ * cChunkDef::Width ); */ NIBBLETYPE BlockMeta = a_Chunk->GetMeta(x, y, z); if (BlockMeta == 0x0f) { // The fire burnt out completely FLOG("FS: Fire at {%d, %d, %d} burnt out, removing the fire block", itr->x + a_ChunkX * cChunkDef::Width, itr->y, itr->z + a_ChunkZ * cChunkDef::Width ); a_Chunk->SetBlock(itr->x, itr->y, itr->z, E_BLOCK_AIR, 0); RemoveFuelNeighbors(a_Chunk, itr->x, itr->y, itr->z); itr = Data.erase(itr); continue; } if ((itr->y > 0) && (!DoesBurnForever(a_Chunk->GetBlock(itr->x, itr->y - 1, itr->z)))) { a_Chunk->SetMeta(x, y, z, BlockMeta + 1); } itr->Data = GetBurnStepTime(a_Chunk, itr->x, itr->y, itr->z); // TODO: Add some randomness into this } // for itr - Data[] }
void cFireSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) { cCoordWithIntList & Data = a_Chunk->GetFireSimulatorData(); int NumMSecs = (int)a_Dt; for (cCoordWithIntList::iterator itr = Data.begin(); itr != Data.end();) { int idx = cChunkDef::MakeIndexNoCheck(itr->x, itr->y, itr->z); BLOCKTYPE BlockType = a_Chunk->GetBlock(idx); if (!IsAllowedBlock(BlockType)) { // The block is no longer eligible (not a fire block anymore; a player probably placed a block over the fire) FLOG("FS: Removing block {%d, %d, %d}", itr->x + a_ChunkX * cChunkDef::Width, itr->y, itr->z + a_ChunkZ * cChunkDef::Width ); itr = Data.erase(itr); continue; } // Try to spread the fire: TrySpreadFire(a_Chunk, itr->x, itr->y, itr->z); itr->Data -= NumMSecs; if (itr->Data >= 0) { // Not yet, wait for it longer ++itr; continue; } // Burn out the fire one step by increasing the meta: /* FLOG("FS: Fire at {%d, %d, %d} is stepping", itr->x + a_ChunkX * cChunkDef::Width, itr->y, itr->z + a_ChunkZ * cChunkDef::Width ); */ NIBBLETYPE BlockMeta = a_Chunk->GetMeta(idx); if (BlockMeta == 0x0f) { // The fire burnt out completely FLOG("FS: Fire at {%d, %d, %d} burnt out, removing the fire block", itr->x + a_ChunkX * cChunkDef::Width, itr->y, itr->z + a_ChunkZ * cChunkDef::Width ); a_Chunk->SetBlock(itr->x, itr->y, itr->z, E_BLOCK_AIR, 0); RemoveFuelNeighbors(a_Chunk, itr->x, itr->y, itr->z); itr = Data.erase(itr); continue; } a_Chunk->SetMeta(idx, BlockMeta + 1); itr->Data = GetBurnStepTime(a_Chunk, itr->x, itr->y, itr->z); // TODO: Add some randomness into this } // for itr - Data[] }