Beispiel #1
0
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[]
}
Beispiel #2
0
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[]
}