// TODO: some cleaning? public void OnBlockUpdate(BlockEventData data, Dictionary <BlockFace, BlockEventData> neighbours, params int[] args) { short sourceDistance = data.chunk.GetParameterValue(new BlockParameter(data.LocalPosition, ParameterType.WATER_SOURCE_DISTANCE)); BlockType belowBlock = neighbours[BlockFace.BOTTOM].blockType; // checl for WATER_SOURCE_DISTANCE in neighbour blocks short biggestSourceDistance = 0; for (int i = 2; i < 6; i++) { BlockEventData blockUpdateEventData = neighbours[(BlockFace)i]; int index = Utils.BlockPosition3DtoIndex(blockUpdateEventData.LocalPosition); BlockType type = blockUpdateEventData.chunk.blocks[index]; if (type == BlockType.WATER) { BlockParameter param = new BlockParameter(blockUpdateEventData.LocalPosition, ParameterType.WATER_SOURCE_DISTANCE); short neighbourSourceDistance = blockUpdateEventData.chunk.GetParameterValue(param); if (neighbourSourceDistance > biggestSourceDistance) { biggestSourceDistance = neighbourSourceDistance; } } } if (WorldData.GetBlockState(belowBlock) == BlockState.SOLID) { // check only side blocks for (int i = 2; i < 6; i++) { BlockEventData blockUpdateEventData = neighbours[(BlockFace)i]; Chunk chunk = blockUpdateEventData.chunk; BlockParameter param = new BlockParameter(blockUpdateEventData.LocalPosition, ParameterType.WATER_SOURCE_DISTANCE); int index = Utils.BlockPosition3DtoIndex(blockUpdateEventData.LocalPosition); BlockType type = chunk.blocks[index]; if (sourceDistance > 0) { if (type == BlockType.AIR || WorldData.GetBlockState(type) == BlockState.PLANTS) { chunk.AddParameterToList(param, (short)(sourceDistance - 1)); chunk.AddBlockToBuildList(new BlockData(BlockType.WATER, blockUpdateEventData.LocalPosition)); World.ScheduleUpdate(chunk, blockUpdateEventData.LocalPosition, 2); } if (type == BlockType.WATER) { // if neighbour block is WATER and neighbour sourceDistance is smaller, update neighbour sourceDistance if (chunk.GetParameterValue(param) < sourceDistance - 1) { chunk.AddParameterToList(param, (short)(sourceDistance - 1)); chunk.AddBlockToBuildList(new BlockData(BlockType.WATER, blockUpdateEventData.LocalPosition)); } } } } } // if block below is AIR or WATER or PLANTS, replace block with full WATER block else if (belowBlock == BlockType.AIR || belowBlock == BlockType.WATER || WorldData.GetBlockState(belowBlock) == BlockState.PLANTS) { data.chunk.AddParameterToList(new BlockParameter(neighbours[BlockFace.BOTTOM].LocalPosition, ParameterType.WATER_SOURCE_DISTANCE), 8); data.chunk.AddBlockToBuildList(new BlockData(BlockType.WATER, neighbours[BlockFace.BOTTOM].LocalPosition)); } // if water is not full block, check if has neighbour with bigger SourceDistance if (sourceDistance != 8 && biggestSourceDistance <= sourceDistance) { // if sourceDistance == 0, replace block with air if (sourceDistance == 0) { data.chunk.ClearParameters(data.LocalPosition); data.chunk.AddBlockToBuildList(new BlockData(BlockType.AIR, data.LocalPosition)); if (belowBlock == BlockType.WATER) { BlockEventData blockUpdateEventData = neighbours[BlockFace.BOTTOM]; data.chunk.AddParameterToList(new BlockParameter(blockUpdateEventData.LocalPosition, ParameterType.WATER_SOURCE_DISTANCE), (short)7); World.ScheduleUpdate(blockUpdateEventData.chunk, blockUpdateEventData.LocalPosition, 1); } } // else, decrease sourceDistance by 1 else { data.chunk.AddParameterToList(new BlockParameter(data.LocalPosition, ParameterType.WATER_SOURCE_DISTANCE), (short)(sourceDistance - 1)); data.chunk.AddBlockToBuildList(new BlockData(BlockType.WATER, data.LocalPosition)); } } }