コード例 #1
0
        public override void OnNeighborBlockChanged(int x, int y, int z, int neighborX, int neighborY, int neighborZ)
        {
            base.OnNeighborBlockChanged(x, y, z, neighborX, neighborY, neighborZ);
            WorldSettings worldSettings = m_subsystemGameInfo.WorldSettings;

            if (worldSettings.EnvironmentBehaviorMode == EnvironmentBehaviorMode.Living && y > 0 && y > worldSettings.TerrainLevel + worldSettings.SeaLevelOffset && (neighborX != x || neighborY != y || neighborZ != z))
            {
                Terrain terrain = SubsystemTerrain.Terrain;
                if (BlocksManager.Blocks[terrain.GetCellContents(x, y - 1, z)].IsFluidBlocker || BlocksManager.Blocks[terrain.GetCellContents(x, y - 1, z)].IsFluidBlocker)
                {
                    return;
                }
                int i = y;
                while (i < 128 && Terrain.ExtractContents(terrain.GetCellValue(x, i, z)) == 18)
                {
                    i++;
                }
                SubsystemTerrain.DestroyCell(0, x, i - 1, z, 0, false, false);
            }
        }
コード例 #2
0
        public void DestroyCell(int toolLevel, int x, int y, int z, int newValue, bool noDrop, bool noParticleSystem)
        {
            int   cellValue = Terrain.GetCellValue(x, y, z);
            int   num       = Terrain.ExtractContents(cellValue);
            Block block     = BlocksManager.Blocks[num];

            if (num != 0)
            {
                bool showDebris = true;
                if (!noDrop)
                {
                    m_dropValues.Clear();
                    block.GetDropValues(this, cellValue, newValue, toolLevel, m_dropValues, out showDebris);
                    for (int i = 0; i < m_dropValues.Count; i++)
                    {
                        BlockDropValue dropValue = m_dropValues[i];
                        if (dropValue.Count > 0)
                        {
                            SubsystemBlockBehavior[] blockBehaviors = m_subsystemBlockBehaviors.GetBlockBehaviors(Terrain.ExtractContents(dropValue.Value));
                            for (int j = 0; j < blockBehaviors.Length; j++)
                            {
                                blockBehaviors[j].OnItemHarvested(x, y, z, cellValue, ref dropValue, ref newValue);
                            }
                            if (dropValue.Count > 0 && Terrain.ExtractContents(dropValue.Value) != 0)
                            {
                                Vector3 position = new Vector3(x, y, z) + new Vector3(0.5f);
                                m_subsystemPickables.AddPickable(dropValue.Value, dropValue.Count, position, null, null);
                            }
                        }
                    }
                }
                if (showDebris && !noParticleSystem && m_subsystemViews.CalculateDistanceFromNearestView(new Vector3(x, y, z)) < 16f)
                {
                    m_subsystemParticles.AddParticleSystem(block.CreateDebrisParticleSystem(this, new Vector3((float)x + 0.5f, (float)y + 0.5f, (float)z + 0.5f), cellValue, 1f));
                }
            }
            ChangeCell(x, y, z, newValue);
        }
コード例 #3
0
        public bool MovePiston(Point3 position, int length)
        {
            Terrain    terrain      = m_subsystemTerrain.Terrain;
            int        data         = Terrain.ExtractData(terrain.GetCellValue(position.X, position.Y, position.Z));
            int        face         = PistonBlock.GetFace(data);
            PistonMode mode         = PistonBlock.GetMode(data);
            int        maxExtension = PistonBlock.GetMaxExtension(data);
            int        pullCount    = PistonBlock.GetPullCount(data);
            int        speed        = PistonBlock.GetSpeed(data);
            Point3     point        = CellFace.FaceToPoint3(face);

            length = MathUtils.Clamp(length, 0, maxExtension + 1);
            int num = 0;

            m_movingBlocks.Clear();
            Point3      offset = point;
            MovingBlock item;

            while (m_movingBlocks.Count < 8)
            {
                int cellValue = terrain.GetCellValue(position.X + offset.X, position.Y + offset.Y, position.Z + offset.Z);
                int num2      = Terrain.ExtractContents(cellValue);
                int face2     = PistonHeadBlock.GetFace(Terrain.ExtractData(cellValue));
                if (num2 != 238 || face2 != face)
                {
                    break;
                }
                DynamicArray <MovingBlock> movingBlocks = m_movingBlocks;
                item = new MovingBlock
                {
                    Offset = offset,
                    Value  = cellValue
                };
                movingBlocks.Add(item);
                offset += point;
                num++;
            }
            if (length > num)
            {
                DynamicArray <MovingBlock> movingBlocks2 = m_movingBlocks;
                item = new MovingBlock
                {
                    Offset = Point3.Zero,
                    Value  = Terrain.MakeBlockValue(238, 0, PistonHeadBlock.SetFace(PistonHeadBlock.SetMode(PistonHeadBlock.SetIsShaft(0, num > 0), mode), face))
                };
                movingBlocks2.Add(item);
                int num3 = 0;
                while (num3 < 8)
                {
                    int cellValue2 = terrain.GetCellValue(position.X + offset.X, position.Y + offset.Y, position.Z + offset.Z);
                    if (!IsBlockMovable(cellValue2, face, position.Y + offset.Y, out bool isEnd))
                    {
                        break;
                    }
                    DynamicArray <MovingBlock> movingBlocks3 = m_movingBlocks;
                    item = new MovingBlock
                    {
                        Offset = offset,
                        Value  = cellValue2
                    };
                    movingBlocks3.Add(item);
                    num3++;
                    offset += point;
                    if (isEnd)
                    {
                        break;
                    }
                }
                if (!IsBlockBlocking(terrain.GetCellValue(position.X + offset.X, position.Y + offset.Y, position.Z + offset.Z)))
                {
                    GetSpeedAndSmoothness(speed, out float speed2, out Vector2 smoothness);
                    Point3 p = position + (length - num) * point;
                    if (m_subsystemMovingBlocks.AddMovingBlockSet(new Vector3(position) + 0.01f * new Vector3(point), new Vector3(p), speed2, 0f, 0f, smoothness, m_movingBlocks, "Piston", position, testCollision: true) != null)
                    {
                        m_allowPistonHeadRemove = true;
                        try
                        {
                            foreach (MovingBlock movingBlock in m_movingBlocks)
                            {
                                if (movingBlock.Offset != Point3.Zero)
                                {
                                    m_subsystemTerrain.ChangeCell(position.X + movingBlock.Offset.X, position.Y + movingBlock.Offset.Y, position.Z + movingBlock.Offset.Z, 0);
                                }
                            }
                        }
                        finally
                        {
                            m_allowPistonHeadRemove = false;
                        }
                        m_subsystemTerrain.ChangeCell(position.X, position.Y, position.Z, Terrain.MakeBlockValue(237, 0, PistonBlock.SetIsExtended(data, isExtended: true)));
                        m_subsystemAudio.PlaySound("Audio/Piston", 1f, 0f, new Vector3(position), 2f, autoDelay: true);
                    }
                }
                return(false);
            }
            if (length < num)
            {
                if (mode != 0)
                {
                    int num4 = 0;
                    for (int i = 0; i < pullCount + 1; i++)
                    {
                        int cellValue3 = terrain.GetCellValue(position.X + offset.X, position.Y + offset.Y, position.Z + offset.Z);
                        if (!IsBlockMovable(cellValue3, face, position.Y + offset.Y, out bool isEnd2))
                        {
                            break;
                        }
                        DynamicArray <MovingBlock> movingBlocks4 = m_movingBlocks;
                        item = new MovingBlock
                        {
                            Offset = offset,
                            Value  = cellValue3
                        };
                        movingBlocks4.Add(item);
                        offset += point;
                        num4++;
                        if (isEnd2)
                        {
                            break;
                        }
                    }
                    if (mode == PistonMode.StrictPulling && num4 < pullCount + 1)
                    {
                        return(false);
                    }
                }
                GetSpeedAndSmoothness(speed, out float speed3, out Vector2 smoothness2);
                float   s = (length == 0) ? 0.01f : 0f;
                Vector3 targetPosition = new Vector3(position) + (length - num) * new Vector3(point) + s * new Vector3(point);
                if (m_subsystemMovingBlocks.AddMovingBlockSet(new Vector3(position), targetPosition, speed3, 0f, 0f, smoothness2, m_movingBlocks, "Piston", position, testCollision: true) != null)
                {
                    m_allowPistonHeadRemove = true;
                    try
                    {
                        foreach (MovingBlock movingBlock2 in m_movingBlocks)
                        {
                            m_subsystemTerrain.ChangeCell(position.X + movingBlock2.Offset.X, position.Y + movingBlock2.Offset.Y, position.Z + movingBlock2.Offset.Z, 0);
                        }
                    }
                    finally
                    {
                        m_allowPistonHeadRemove = false;
                    }
                    m_subsystemAudio.PlaySound("Audio/Piston", 1f, 0f, new Vector3(position), 2f, autoDelay: true);
                }
                return(false);
            }
            return(true);
        }
コード例 #4
0
        public void GenerateGeometry(MovingBlockSet movingBlockSet)
        {
            Point3 point = default(Point3);

            point.X = ((movingBlockSet.CurrentVelocity.X > 0f) ? ((int)MathUtils.Floor(movingBlockSet.Position.X)) : (point.X = (int)MathUtils.Ceiling(movingBlockSet.Position.X)));
            point.Y = ((movingBlockSet.CurrentVelocity.Y > 0f) ? ((int)MathUtils.Floor(movingBlockSet.Position.Y)) : (point.Y = (int)MathUtils.Ceiling(movingBlockSet.Position.Y)));
            point.Z = ((movingBlockSet.CurrentVelocity.Z > 0f) ? ((int)MathUtils.Floor(movingBlockSet.Position.Z)) : (point.Z = (int)MathUtils.Ceiling(movingBlockSet.Position.Z)));
            if (!(point != movingBlockSet.GeometryGenerationPosition))
            {
                return;
            }
            Point3 p      = new Point3(movingBlockSet.Box.Left, movingBlockSet.Box.Top, movingBlockSet.Box.Near);
            Point3 point2 = new Point3(movingBlockSet.Box.Width, movingBlockSet.Box.Height, movingBlockSet.Box.Depth);

            point2.Y = MathUtils.Min(point2.Y, 254);
            if (m_blockGeometryGenerator == null)
            {
                int x = 2;
                x = (int)MathUtils.NextPowerOf2((uint)x);
                m_blockGeometryGenerator = new BlockGeometryGenerator(new Terrain(), m_subsystemTerrain, null, base.Project.FindSubsystem <SubsystemFurnitureBlockBehavior>(throwOnError: true), null, base.Project.FindSubsystem <SubsystemPalette>(throwOnError: true));
                for (int i = 0; i < x; i++)
                {
                    for (int j = 0; j < x; j++)
                    {
                        m_blockGeometryGenerator.Terrain.AllocateChunk(i, j);
                    }
                }
            }
            Terrain terrain = m_subsystemTerrain.Terrain;

            for (int k = 0; k < point2.X + 2; k++)
            {
                for (int l = 0; l < point2.Z + 2; l++)
                {
                    int x2         = k + p.X + point.X - 1;
                    int z          = l + p.Z + point.Z - 1;
                    int shaftValue = terrain.GetShaftValue(x2, z);
                    m_blockGeometryGenerator.Terrain.SetTemperature(k, l, Terrain.ExtractTemperature(shaftValue));
                    m_blockGeometryGenerator.Terrain.SetHumidity(k, l, Terrain.ExtractHumidity(shaftValue));
                    for (int m = 0; m < point2.Y + 2; m++)
                    {
                        int y     = m + p.Y + point.Y - 1;
                        int light = Terrain.ExtractLight(terrain.GetCellValue(x2, y, z));
                        m_blockGeometryGenerator.Terrain.SetCellValueFast(k, m, l, Terrain.MakeBlockValue(0, light, 0));
                    }
                }
            }
            m_blockGeometryGenerator.Terrain.SeasonTemperature = terrain.SeasonTemperature;
            m_blockGeometryGenerator.Terrain.SeasonHumidity    = terrain.SeasonHumidity;
            foreach (MovingBlock block in movingBlockSet.Blocks)
            {
                int x3    = block.Offset.X - p.X + 1;
                int y2    = block.Offset.Y - p.Y + 1;
                int z2    = block.Offset.Z - p.Z + 1;
                int value = Terrain.ReplaceLight(light: m_blockGeometryGenerator.Terrain.GetCellLightFast(x3, y2, z2), value: block.Value);
                m_blockGeometryGenerator.Terrain.SetCellValueFast(x3, y2, z2, value);
            }
            m_blockGeometryGenerator.ResetCache();
            movingBlockSet.Vertices.Clear();
            movingBlockSet.Indices.Clear();
            for (int n = 1; n < point2.X + 1; n++)
            {
                for (int num = 1; num < point2.Y + 1; num++)
                {
                    for (int num2 = 1; num2 < point2.Z + 1; num2++)
                    {
                        int cellValueFast = m_blockGeometryGenerator.Terrain.GetCellValueFast(n, num, num2);
                        int num3          = Terrain.ExtractContents(cellValueFast);
                        if (num3 != 0)
                        {
                            BlocksManager.Blocks[num3].GenerateTerrainVertices(m_blockGeometryGenerator, movingBlockSet.Geometry, cellValueFast, n, num, num2);
                        }
                    }
                }
            }
            movingBlockSet.GeometryOffset             = new Vector3(p) - new Vector3(1f);
            movingBlockSet.GeometryGenerationPosition = point;
        }
コード例 #5
0
        public TerrainRaycastResult?Raycast(Vector3 start, Vector3 end, bool useInteractionBoxes, bool skipAirBlocks, Func <int, float, bool> action)
        {
            float num = Vector3.Distance(start, end);

            if (num > 1000f)
            {
                Log.Warning("Terrain raycast too long, trimming.");
                end = start + 1000f * Vector3.Normalize(end - start);
            }
            Ray3  ray   = new Ray3(start, Vector3.Normalize(end - start));
            float x     = start.X;
            float y     = start.Y;
            float z     = start.Z;
            float x2    = end.X;
            float y2    = end.Y;
            float z2    = end.Z;
            int   num2  = Terrain.ToCell(x);
            int   num3  = Terrain.ToCell(y);
            int   num4  = Terrain.ToCell(z);
            int   num5  = Terrain.ToCell(x2);
            int   num6  = Terrain.ToCell(y2);
            int   num7  = Terrain.ToCell(z2);
            int   num8  = (x < x2) ? 1 : ((x > x2) ? (-1) : 0);
            int   num9  = (y < y2) ? 1 : ((y > y2) ? (-1) : 0);
            int   num10 = (z < z2) ? 1 : ((z > z2) ? (-1) : 0);
            float num11 = MathUtils.Floor(x);
            float num12 = num11 + 1f;
            float num13 = ((x > x2) ? (x - num11) : (num12 - x)) / Math.Abs(x2 - x);
            float num14 = MathUtils.Floor(y);
            float num15 = num14 + 1f;
            float num16 = ((y > y2) ? (y - num14) : (num15 - y)) / Math.Abs(y2 - y);
            float num17 = MathUtils.Floor(z);
            float num18 = num17 + 1f;
            float num19 = ((z > z2) ? (z - num17) : (num18 - z)) / Math.Abs(z2 - z);
            float num20 = 1f / Math.Abs(x2 - x);
            float num21 = 1f / Math.Abs(y2 - y);
            float num22 = 1f / Math.Abs(z2 - z);

            while (true)
            {
                BoundingBox boundingBox       = default(BoundingBox);
                int         collisionBoxIndex = 0;
                float?      num23             = null;
                int         cellValue         = Terrain.GetCellValue(num2, num3, num4);
                int         num24             = Terrain.ExtractContents(cellValue);
                if (num24 != 0 || !skipAirBlocks)
                {
                    Ray3        ray2 = new Ray3(ray.Position - new Vector3(num2, num3, num4), ray.Direction);
                    int         nearestBoxIndex;
                    BoundingBox nearestBox;
                    float?      num25 = BlocksManager.Blocks[num24].Raycast(ray2, this, cellValue, useInteractionBoxes, out nearestBoxIndex, out nearestBox);
                    if (num25.HasValue && (!num23.HasValue || num25.Value < num23.Value))
                    {
                        num23             = num25;
                        collisionBoxIndex = nearestBoxIndex;
                        boundingBox       = nearestBox;
                    }
                }
                if (num23.HasValue && num23.Value <= num && (action == null || action(cellValue, num23.Value)))
                {
                    int     face   = 0;
                    Vector3 vector = start - new Vector3(num2, num3, num4) + num23.Value * ray.Direction;
                    float   num26  = float.MaxValue;
                    float   num27  = MathUtils.Abs(vector.X - boundingBox.Min.X);
                    if (num27 < num26)
                    {
                        num26 = num27;
                        face  = 3;
                    }
                    num27 = MathUtils.Abs(vector.X - boundingBox.Max.X);
                    if (num27 < num26)
                    {
                        num26 = num27;
                        face  = 1;
                    }
                    num27 = MathUtils.Abs(vector.Y - boundingBox.Min.Y);
                    if (num27 < num26)
                    {
                        num26 = num27;
                        face  = 5;
                    }
                    num27 = MathUtils.Abs(vector.Y - boundingBox.Max.Y);
                    if (num27 < num26)
                    {
                        num26 = num27;
                        face  = 4;
                    }
                    num27 = MathUtils.Abs(vector.Z - boundingBox.Min.Z);
                    if (num27 < num26)
                    {
                        num26 = num27;
                        face  = 2;
                    }
                    num27 = MathUtils.Abs(vector.Z - boundingBox.Max.Z);
                    if (num27 < num26)
                    {
                        num26 = num27;
                        face  = 0;
                    }
                    TerrainRaycastResult value = default(TerrainRaycastResult);
                    value.Ray      = ray;
                    value.Value    = cellValue;
                    value.CellFace = new CellFace
                    {
                        X    = num2,
                        Y    = num3,
                        Z    = num4,
                        Face = face
                    };
                    value.CollisionBoxIndex = collisionBoxIndex;
                    value.Distance          = num23.Value;
                    return(value);
                }
                if (num13 <= num16 && num13 <= num19)
                {
                    if (num2 == num5)
                    {
                        break;
                    }
                    num13 += num20;
                    num2  += num8;
                }
                else if (num16 <= num13 && num16 <= num19)
                {
                    if (num3 == num6)
                    {
                        break;
                    }
                    num16 += num21;
                    num3  += num9;
                }
                else
                {
                    if (num4 == num7)
                    {
                        break;
                    }
                    num19 += num22;
                    num4  += num10;
                }
            }
            return(null);
        }