예제 #1
0
    /// <summary>
    /// Update a specific voxel (Called from world update thread)
    /// </summary>
    public override bool UpdateVoxel(uint Tick, Point LocalPosition, VoxelInstance Voxel, VoxelChunk Chunk)
    {
        // Perform cleanup, if liquid too small
        if (Tick % mCleanRate == 0 && mRandom.Next(0, 100) < mCleanPercent)
        {
            // Replace with air, if no fill
            if (Voxel.mMetaFlags <= 1)
            {
                Voxel.SetNew(0);
                return(true);
            }
        }

        // Attempt to settle liquids other than puddles (Put at multiple of 2)
        if (Tick % mSettleRate == 0 && Voxel.mMetaFlags > 1)
        {
            if (Voxel.mMetaFlags % 2 != 0)
            {
                Voxel.mMetaFlags--;
                return(true);
            }
            if (Voxel.mMetaFlags == 0)
            {
                Voxel.SetNew(0);
                return(true);
            }
        }

        // Only update at given tick rate
        if (Tick % mUpdateRate != 0)
        {
            return(false);
        }


        // Clamp liquid to max height
        if (Voxel.mMetaFlags > VoxelData_Liquid.MaxHeight)
        {
            Voxel.mMetaFlags = (ushort)VoxelData_Liquid.MaxHeight;
        }


        ushort startHeight = Voxel.mMetaFlags;

        VoxelInstance above = Chunk.Get(LocalPosition.x, LocalPosition.y + 1, LocalPosition.z);
        VoxelInstance below = Chunk.Get(LocalPosition.x, LocalPosition.y - 1, LocalPosition.z);
        VoxelInstance left  = Chunk.Get(LocalPosition.x - 1, LocalPosition.y, LocalPosition.z);
        VoxelInstance right = Chunk.Get(LocalPosition.x + 1, LocalPosition.y, LocalPosition.z);
        VoxelInstance front = Chunk.Get(LocalPosition.x, LocalPosition.y, LocalPosition.z - 1);
        VoxelInstance back  = Chunk.Get(LocalPosition.x, LocalPosition.y, LocalPosition.z + 1);


        // Move liquid down and then out
        AttemptLiquidDisperse(Voxel, below, true);
        AttemptAirDisperse(Voxel, below, true);

        if (Voxel.mMetaFlags > 1)
        {
            // Shuffle order everytime to prevent any flattening issues
            uint order = (uint)mRandom.Next(0, 4);

            switch (order)
            {
            case 0:
                AttemptAirDisperse(Voxel, left);
                AttemptAirDisperse(Voxel, right);
                AttemptAirDisperse(Voxel, front);
                AttemptAirDisperse(Voxel, back);

                AttemptLiquidDisperse(Voxel, left);
                AttemptLiquidDisperse(Voxel, right);
                AttemptLiquidDisperse(Voxel, front);
                AttemptLiquidDisperse(Voxel, back);
                break;

            case 1:
                AttemptAirDisperse(Voxel, back);
                AttemptAirDisperse(Voxel, left);
                AttemptAirDisperse(Voxel, right);
                AttemptAirDisperse(Voxel, front);

                AttemptLiquidDisperse(Voxel, back);
                AttemptLiquidDisperse(Voxel, left);
                AttemptLiquidDisperse(Voxel, right);
                AttemptLiquidDisperse(Voxel, front);
                break;

            case 2:
                AttemptAirDisperse(Voxel, front);
                AttemptAirDisperse(Voxel, back);
                AttemptAirDisperse(Voxel, left);
                AttemptAirDisperse(Voxel, right);

                AttemptLiquidDisperse(Voxel, front);
                AttemptLiquidDisperse(Voxel, back);
                AttemptLiquidDisperse(Voxel, left);
                AttemptLiquidDisperse(Voxel, right);
                break;

            case 3:
                AttemptAirDisperse(Voxel, right);
                AttemptAirDisperse(Voxel, front);
                AttemptAirDisperse(Voxel, back);
                AttemptAirDisperse(Voxel, left);

                AttemptLiquidDisperse(Voxel, right);
                AttemptLiquidDisperse(Voxel, front);
                AttemptLiquidDisperse(Voxel, back);
                AttemptLiquidDisperse(Voxel, left);
                break;
            }
        }


        // Replace with air, if no fill
        if (Voxel.mMetaFlags == 0)
        {
            Voxel.SetNew(0);
            return(true);
        }

        return(Voxel.mMetaFlags != startHeight);
    }