/// <summary> /// Sets the block data at given world coordinates, updates the chunk and its /// neighbors if the Update chunk flag is true or not set. /// </summary> /// <param name="pos">Global position of the block</param> /// <param name="blockData">The block be placed</param> /// <param name="setBlockModified">Set to true to mark chunk data as modified</param> /// <param name="onModified">Action to perform once the operation finished</param> public void Modify(ref Vector3Int pos, BlockData blockData, bool setBlockModified, Action <ModifyBlockContext> onModified = null) { Vector3Int chunkPos = Chunk.ContainingChunkPos(ref pos); Chunk chunk = world.chunks.Get(ref chunkPos); if (chunk == null) { return; } Vector3Int blockPos = new Vector3Int( Helpers.Mod(pos.x, Env.ChunkSize), Helpers.Mod(pos.y, Env.ChunkSize), Helpers.Mod(pos.z, Env.ChunkSize) ); int index = Helpers.GetChunkIndex1DFrom3D(blockPos.x, blockPos.y, blockPos.z); // Nothing for us to do if the block did not change BlockData oldBlockData = chunk.blocks.Get(index); if (oldBlockData.Type == blockData.Type) { return; } ModifyBlockContext context = null; if (onModified != null) { context = new ModifyBlockContext(onModified, world, index, index, blockData, setBlockModified); } chunk.blocks.Modify(new ModifyOpBlock(blockData, index, setBlockModified, context)); }
/// <summary> /// Performs a ranged set operation of ellipsoid shape /// </summary> /// <param name="blockData">BlockData to place at the given location</param> /// <param name="min">Starting positon in local chunk coordinates</param> /// <param name="max">Ending position in local chunk coordinates</param> /// <param name="offset"></param> /// <param name="a2inv"></param> /// <param name="b2inv"></param> /// <param name="setBlockModified">Set to true to mark chunk data as modified</param> /// <param name="parentContext">Context of a parent which performed this operation</param> public ModifyOpEllipsoid(BlockData blockData, Vector3Int min, Vector3Int max, Vector3Int offset, float a2inv, float b2inv, bool setBlockModified, ModifyBlockContext parentContext = null) : base(blockData, min, max, setBlockModified, parentContext) { this.offset = offset; this.a2inv = a2inv; this.b2inv = b2inv; }
/// <summary> /// Queues a modification of blocks in a given range /// </summary> /// <param name="posFrom">Starting positon in local chunk coordinates</param> /// <param name="posTo">Ending position in local chunk coordinates</param> /// <param name="blockData">BlockData to place at the given location</param> /// <param name="setBlockModified">Set to true to mark chunk data as modified</param> /// <param name="onModified">Action to perform once the operation finished</param> public void ModifyBlockDataRanged(ref Vector3Int posFrom, ref Vector3Int posTo, BlockData blockData, bool setBlockModified, Action <ModifyBlockContext> onModified = null) { // Let's make sure that ranges are okay if (posFrom.x > posTo.x || posFrom.y > posTo.y || posFrom.z > posTo.z) { return; } Vector3Int chunkPosFrom = Helpers.ContainingChunkPos(ref posFrom); Vector3Int chunkPosTo = Helpers.ContainingChunkPos(ref posTo); ModifyBlockContext context = null; if (onModified != null) { context = new ModifyBlockContext(onModified, this, Helpers.GetChunkIndex1DFrom3D(posFrom.x, posFrom.y, posFrom.z), Helpers.GetChunkIndex1DFrom3D(posTo.x, posTo.y, posTo.z), blockData, setBlockModified); } // Update all chunks in range int minY = Helpers.Mod(posFrom.y, Env.ChunkSize); for (int cy = chunkPosFrom.y; cy <= chunkPosTo.y; cy += Env.ChunkSize, minY = 0) { int maxY = Math.Min(posTo.y - cy, Env.ChunkSize1); int minZ = Helpers.Mod(posFrom.z, Env.ChunkSize); for (int cz = chunkPosFrom.z; cz <= chunkPosTo.z; cz += Env.ChunkSize, minZ = 0) { int maxZ = Math.Min(posTo.z - cz, Env.ChunkSize1); int minX = Helpers.Mod(posFrom.x, Env.ChunkSize); for (int cx = chunkPosFrom.x; cx <= chunkPosTo.x; cx += Env.ChunkSize, minX = 0) { Vector3Int chunkPos = new Vector3Int(cx, cy, cz); Chunk chunk = GetChunk(ref chunkPos); if (chunk == null) { continue; } int maxX = Math.Min(posTo.x - cx, Env.ChunkSize1); chunk.Modify( new ModifyOpCuboid( blockData, new Vector3Int(minX, minY, minZ), new Vector3Int(maxX, maxY, maxZ), setBlockModified, context) ); } } } }
protected ModifyOp(BlockData blockData, bool setBlockModified, ModifyBlockContext parentContext = null) { this.parentContext = parentContext; this.blockData = blockData; this.setBlockModified = setBlockModified; if (parentContext != null) { parentContext.RegisterChildAction(); } }
/// <summary> /// Sets the block data at given world coordinates, updates the chunk and its /// neighbors if the Update chunk flag is true or not set. /// </summary> /// <param name="pos">Global position of the block</param> /// <param name="blockData">The block be placed</param> /// <param name="setBlockModified">Set to true to mark chunk data as modified</param> /// <param name="onModified">Action to perform once the operation finished</param> public void ModifyBlockData(ref Vector3Int pos, BlockData blockData, bool setBlockModified, Action <ModifyBlockContext> onModified = null) { // Transform the position into chunk coordinates Vector3Int chunkPos = Helpers.ContainingChunkPos(ref pos); Chunk chunk = GetChunk(ref chunkPos); if (chunk == null) { return; } int index = Helpers.GetChunkIndex1DFrom3D( Helpers.Mod(pos.x, Env.ChunkSize), Helpers.Mod(pos.y, Env.ChunkSize), Helpers.Mod(pos.z, Env.ChunkSize) ); // Nothing for us to do if the block did not change BlockData oldBlockData = chunk.Blocks.Get(index); if (oldBlockData.Type == blockData.Type) { return; } ModifyBlockContext context = null; if (onModified != null) { context = new ModifyBlockContext(onModified, this, index, index, blockData, setBlockModified); } chunk.Modify(new ModifyOpBlock(blockData, index, setBlockModified, context)); }
public void RegisterModifyRange(ModifyBlockContext onModified) { modifyRangeQueue.Add(onModified); }
/// <summary> /// Performs a ranged set operation of cuboid shape /// </summary> /// <param name="blockData">BlockData to place at the given location</param> /// <param name="min">Starting positon in local chunk coordinates</param> /// <param name="max">Ending position in local chunk coordinates</param> /// <param name="setBlockModified">Set to true to mark chunk data as modified</param> /// <param name="parentContext">Context of a parent which performed this operation</param> public ModifyOpCuboid(BlockData blockData, Vector3Int min, Vector3Int max, bool setBlockModified, ModifyBlockContext parentContext = null) : base(blockData, min, max, setBlockModified, parentContext) { }
protected ModifyOpRange(BlockData blockData, Vector3Int min, Vector3Int max, bool setBlockModified, ModifyBlockContext parentContext = null) : base(blockData, setBlockModified, parentContext) { this.min = min; this.max = max; }