public void Initialize(ChunkPos pos, ChunkManager chunkManager) { for (int x = XOffsetBegin; x <= XOffsetEnd; x++) { for (int z = ZOffsetBegin; z <= ZOffsetEnd; z++) { ChunkPos neighbor = pos.AddOffset(x, z); bool result = chunkManager.GetChunk(neighbor, false, out Chunk chunk); Assert.IsTrue(result); m_Members[x + 1, z + 1] = chunk; } } Accessible = true; }
private void LightBlocks(Stack <Vector3Int> queue, ref int limit, ModificationSource source) { while (limit-- > 0 && queue.Count > 0) { Vector3Int blockPos = queue.Pop(); if (blockPos.y < 0 || blockPos.y >= ChunkHeight) { continue; } if (!ChunkManager.GetChunk(ChunkPos.GetFromAny(blockPos.x, blockPos.z), false, out _)) { // 我不想管这个了,如果有人有好的算法请告诉我! // m_BlocksToLightQueue.Push(blockPos); // break; continue; } int x = blockPos.x; int y = blockPos.y; int z = blockPos.z; BlockData block = RWAccessor.GetBlock(x, y, z); int opacity = Mathf.Max(block.LightOpacity, 1); int finalLight = 0; if (opacity < MaxLight || block.LightValue > 0) // 不然就是0 { int max = RWAccessor.GetAmbientLight(x + 1, y, z); int temp; if ((temp = RWAccessor.GetAmbientLight(x - 1, y, z)) > max) { max = temp; } if ((temp = RWAccessor.GetAmbientLight(x, y + 1, z)) > max) { max = temp; } if ((temp = RWAccessor.GetAmbientLight(x, y - 1, z)) > max) { max = temp; } if ((temp = RWAccessor.GetAmbientLight(x, y, z + 1)) > max) { max = temp; } if ((temp = RWAccessor.GetAmbientLight(x, y, z - 1)) > max) { max = temp; } finalLight = max - opacity; if (block.LightValue > finalLight) { finalLight = block.LightValue; // 假设这个值一定是合法的(不过确实应该是合法的) } else if (finalLight < 0) { finalLight = 0; } //else if (finalLight > MaxLight) //{ // finalLight = MaxLight; //} } if (RWAccessor.SetAmbientLightLevel(x, y, z, finalLight, source)) { queue.Push(new Vector3Int(x - 1, y, z)); queue.Push(new Vector3Int(x, y - 1, z)); queue.Push(new Vector3Int(x, y, z - 1)); queue.Push(new Vector3Int(x + 1, y, z)); queue.Push(new Vector3Int(x, y + 1, z)); queue.Push(new Vector3Int(x, y, z + 1)); } } }
public bool SetBlockType(int worldX, int y, int worldZ, BlockType value, byte state = 0, bool lightBlocks = true, bool tickBlocks = true, bool updateNeighborSections = true) { if (y >= WorldHeight || y < 0) { return(false); } int localX = worldX - PositionX; int localZ = worldZ - PositionZ; if (!m_Data.SetBlockType(localX, y, localZ, value, out BlockType previousBlockType)) { return(false); } m_Data.SetBlockState(localX, y, localZ, state); UpdateHeightMapAndSkyLight(localX, y, localZ); WorldManager world = WorldManager.Active; ChunkManager manager = world.ChunkManager; DataManager dataManager = world.DataManager; Block previousBlock = dataManager.GetBlockByType(previousBlockType); Block block = dataManager.GetBlockByType(value); int sectionIndex = Mathf.FloorToInt(y * OverSectionHeight); int yInSection = y - sectionIndex * SectionHeight; if (previousBlock.HasAnyFlag(BlockFlags.NeedsRandomTick)) { m_Data.DecreaseTickRefCount(sectionIndex); } if (block.HasAnyFlag(BlockFlags.NeedsRandomTick)) { m_Data.IncreaseTickRefCount(sectionIndex); } if (previousBlock.VertexType != BlockVertexType.None) { if (previousBlock.HasAnyFlag(BlockFlags.Liquid)) { m_Data.DecreaseRenderableLiquidCount(sectionIndex); } else { m_Data.DecreaseRenderableSolidCount(sectionIndex); } } if (block.VertexType != BlockVertexType.None) { if (block.HasAnyFlag(BlockFlags.Liquid)) { m_Data.IncreaseRenderableLiquidCount(sectionIndex); } else { m_Data.IncreaseRenderableSolidCount(sectionIndex); } } SetMeshDirty(sectionIndex, GetDirtyFlags(previousBlock, block)); if (lightBlocks) { manager.LightBlock(worldX, y, worldZ); } if (tickBlocks) { manager.TickBlock(worldX, y, worldZ); } if (updateNeighborSections) { if (localX == 0) { Chunk chunk = manager.GetChunk(PositionX - ChunkWidth, PositionZ); chunk?.SetMeshDirty(sectionIndex, MeshDirtyFlags.Both); } else if (localX == ChunkWidth - 1) { Chunk chunk = manager.GetChunk(PositionX + ChunkWidth, PositionZ); chunk?.SetMeshDirty(sectionIndex, MeshDirtyFlags.Both); } if (yInSection == 0 && sectionIndex > 0) { SetMeshDirty(sectionIndex - 1, MeshDirtyFlags.Both); } else if (yInSection == SectionHeight - 1 && sectionIndex < SectionCountInChunk - 1) { SetMeshDirty(sectionIndex + 1, MeshDirtyFlags.Both); } if (localZ == 0) { Chunk chunk = manager.GetChunk(PositionX, PositionZ - ChunkWidth); chunk?.SetMeshDirty(sectionIndex, MeshDirtyFlags.Both); } else if (localZ == ChunkWidth - 1) { Chunk chunk = manager.GetChunk(PositionX, PositionZ + ChunkWidth); chunk?.SetMeshDirty(sectionIndex, MeshDirtyFlags.Both); } } return(m_IsModified = true); }
public byte GetBlockLight(int x, int y, int z) { Chunk chunk = ChunkManager.GetChunk(x, z); return(chunk == null ? WorldConsts.MaxLight : chunk.GetBlockLight(x, y, z)); }
public void SetBlockLight(int x, int y, int z, byte value) { Chunk chunk = ChunkManager.GetChunk(x, z); chunk?.SetBlockLight(x, y, z, value); }
public byte GetFinalLightLevel(int x, int y, int z) { Chunk chunk = ChunkManager.GetChunk(x, z); return(chunk == null ? WorldConsts.MaxLight : chunk.GetFinalLightLevel(x, y, z)); }
public byte GetBlockState(int x, int y, int z) { Chunk chunk = ChunkManager.GetChunk(x, z); return(chunk.GetBlockState(x, y, z)); }
public void SetBlockState(int x, int y, int z, byte value) { Chunk chunk = ChunkManager.GetChunk(x, z); chunk.SetBlockState(x, y, z, value); }
public BlockType GetBlockType(int x, int y, int z) { Chunk chunk = ChunkManager.GetChunk(x, z); return(chunk == null ? BlockType.Air : chunk.GetBlockType(x, y, z)); }
public bool SetBlockType(int x, int y, int z, BlockType block, byte state = 0, bool lightBlocks = true, bool tickBlocks = true, bool updateNeighborSections = true) { Chunk chunk = ChunkManager.GetChunk(x, z); return(chunk.SetBlockType(x, y, z, block, state, lightBlocks, tickBlocks, updateNeighborSections)); }