/// <summary> /// Sets a world in the world to a given ID. /// </summary> /// <param name="blockPos">The block position.</param> /// <param name="blockID">The ID of the block to place.</param> public void SetBlock(BlockPosition blockPos, ushort blockID) { if (blockID >= m_BlockList.BlockCount) { throw new System.ArgumentOutOfRangeException("blockID", $"Invalid block type '{blockID}'!"); } m_WorldContainer.SetBlock(blockPos, blockID); m_WorldContainer.RemeshDirtyChunks(); }
/// <summary> /// Adds the quad normals to the mesh. /// </summary> /// <param name="side">The side of the block.</param> void AddNormals(int side) { var dir = new BlockPosition(0, 0, 0).ShiftAlongDirection(side); var vec = new Vector3(dir.X, dir.Y, dir.Z); for (int i = 0; i < 4; i++) { Mesh.Normals.Add(vec); } }
/// <summary> /// Sets the block ID at the given local block position within the container. /// </summary> /// <param name="pos">The local block position.</param> /// <param name="id">The block ID to assign.</param> /// <exception cref="ArgumentOutOfRangeException"> /// If the block position is not within the container. /// </exception> public void SetBlockID(BlockPosition pos, ushort id) { int index = pos.Index(Size); if (Blocks[index] == id) { return; } Blocks[index] = id; IsModified = true; }
/// <summary> /// Sets the block at the given position. /// </summary> /// <param name="blockPos">The block position.</param> /// <param name="blockID">The block ID to assign.</param> internal void SetBlock(BlockPosition blockPos, ushort blockID) { var chunkPos = blockPos.ToChunkPosition(World.ChunkSize); blockPos &= World.ChunkSize.Mask; var chunk = GetChunk(chunkPos, true); if (chunk.GetBlockID(blockPos) == blockID) { return; } chunk.SetBlockID(blockPos, blockID); RemeshEffectedChunks(blockPos, chunkPos); }
/// <summary> /// Force loads all chunks within a given region, if not already loaded. /// </summary> /// <param name="center">The center of the bounding region.</param> /// <param name="extents">The radius of each axis.</param> public void LoadChunkRegion(Vector3Int center, Vector3Int extents) { var min = center - extents; var max = center + extents; for (int x = min.x; x <= max.x; x++) { for (int y = min.y; y <= max.y; y++) { for (int z = min.z; z <= max.z; z++) { var blockPos = new BlockPosition(x, y, z) * ChunkSize.Value; m_WorldContainer.GetBlock(blockPos, true); } } } }
/// <inheritdoc cref="IEditBatch"/> public IEnumerable <BlockPlacement> GetBlocks() { for (int x = m_Start.X; x <= m_End.X; x++) { for (int y = m_Start.Y; y <= m_End.Y; y++) { for (int z = m_Start.Z; z <= m_End.Z; z++) { var pos = new BlockPosition(x, y, z); yield return(new BlockPlacement { Position = pos, BlockID = m_FillPattern.GetBlockID(pos), }); } } } }
/// <summary> /// Converts the given face rotation enum to a rotation index for the quad builder. /// </summary> /// <param name="pos">The position of the block.</param> /// <param name="rot">The face rotation.</param> /// <returns>The rotation index.</returns> private int SolveRotation(BlockPosition pos, FaceRotation rot) { if (rot == FaceRotation.Random) { long r; r = pos.X * 19; r = r * 17 + pos.Y; r = r * 31 + pos.Z; r = r * 25214903917 + 11; r = r * 25214903917 + 11; r = r * 25214903917 + 11; r = r * 25214903917 + 11; return((int)(r & 0x7)); } return((int)rot); }
/// <summary> /// Determines which chunks should be remeshed based on the given block position. /// </summary> /// <param name="blockPos">The local block position.</param> /// <param name="chunkPos">The chunk position.</param> private void RemeshEffectedChunks(BlockPosition blockPos, ChunkPosition chunkPos) { MarkForRemesh(chunkPos); if (blockPos.X == 0) { MarkForRemesh(chunkPos.ShiftAlongDirection(1)); } if (blockPos.X == World.ChunkSize.Mask) { MarkForRemesh(chunkPos.ShiftAlongDirection(0)); } if (blockPos.Y == 0) { MarkForRemesh(chunkPos.ShiftAlongDirection(3)); } if (blockPos.Y == World.ChunkSize.Mask) { MarkForRemesh(chunkPos.ShiftAlongDirection(2)); } if (blockPos.Z == 0) { MarkForRemesh(chunkPos.ShiftAlongDirection(5)); } if (blockPos.Z == World.ChunkSize.Mask) { MarkForRemesh(chunkPos.ShiftAlongDirection(4)); } RemeshDirtyChunks(); }
/// <inheritdoc cref="IRegionalEdit"/> public void Set(BlockPosition point1, BlockPosition point2, IFillPattern fillPattern) { m_FillPattern = fillPattern; m_Start = MinPos(point1, point2); m_End = MaxPos(point1, point2); }
/// <summary> /// Gets the block ID at the given local block position within the container. /// </summary> /// <param name="pos">The local block position.</param> /// <returns>The block ID.</returns> /// <exception cref="ArgumentOutOfRangeException"> /// If the block position is not within the container. /// </exception> public ushort GetBlockID(BlockPosition pos) { return(Blocks[pos.Index(Size)]); }
/// <inheritdoc cref="IChunkProperties"/> public BlockType GetNextBlock(BlockPosition pos, int side) => m_Ungenerated;
/// <inheritdoc cref="IChunkProperties"/> public BlockType GetBlock(BlockPosition pos) => m_BlockType;
/// <summary> /// Checks whether or not the given quad within the check should be added to the mesh. /// </summary> /// <param name="chunkProperties">The chunk properties to read from.</param> /// <param name="pos">The block position.</param> /// <param name="side">The side of the block being checked.</param> /// <returns>True if the quad should be placed. False otherwise.</returns> protected abstract bool CanPlaceQuad(ChunkProperties chunkProperties, BlockPosition pos, int side);
/// <summary> /// Gets the block type at the given world position. /// /// For ungenerated or unloaded chunks, the Ungenerated block type is return. /// </summary> /// <param name="blockPos">The position of the block.</param> /// <param name="createChunk">Whether or not to create (or load) the chunk if it doesn't currently exist.</param> /// <returns>The block type.</returns> public BlockType GetBlock(BlockPosition blockPos, bool createChunk = false) { ushort blockID = m_WorldContainer.GetBlock(blockPos, createChunk); return(m_BlockList.GetBlockType(blockID)); }
/// <summary> /// Sets a world in the world to a given ID. /// </summary> /// <param name="blockPos">The block position.</param> /// <param name="blockID">The ID of the block to place.</param> internal void SetBlock(BlockPosition blockPos, ushort blockID) => m_ServerThread.RunTask(new SetBlockTask(blockPos, blockID));