Пример #1
0
 public void CopySliceContentsHashes(TerrainChunk chunk)
 {
     for (int i = 0; i < Slices.Length; i++)
     {
         Slices[i].ContentsHash = chunk.SliceContentsHashes[i];
     }
 }
Пример #2
0
        public override void OnBlockRemoved(int value, int newValue, int x, int y, int z)
        {
            if (m_subsystemGameInfo.WorldSettings.EnvironmentBehaviorMode != 0 || m_leavesToCheck.Count >= 5000 || !(BlocksManager.Blocks[Terrain.ExtractContents(value)] is WoodBlock))
            {
                return;
            }
            int num  = x - 3;
            int num2 = MathUtils.Max(y - 3, 0);
            int num3 = z - 3;
            int num4 = x + 3;
            int num5 = MathUtils.Min(y + 3, 255);
            int num6 = z + 3;

            for (int i = num; i <= num4; i++)
            {
                for (int j = num3; j <= num6; j++)
                {
                    TerrainChunk chunkAtCell = base.SubsystemTerrain.Terrain.GetChunkAtCell(i, j);
                    if (chunkAtCell == null)
                    {
                        continue;
                    }
                    int num7 = TerrainChunk.CalculateCellIndex(i & 0xF, 0, j & 0xF);
                    for (int k = num2; k <= num5; k++)
                    {
                        int num8 = Terrain.ExtractContents(chunkAtCell.GetCellValueFast(num7 + k));
                        if (num8 != 0 && BlocksManager.Blocks[num8] is LeavesBlock)
                        {
                            m_leavesToCheck.Add(new Point3(i, k, j));
                        }
                    }
                }
            }
        }
 public void UpdateFluidIsTop(TerrainChunk chunk)
 {
     _ = m_subsystemTerrain.Terrain;
     for (int i = 0; i < 16; i++)
     {
         for (int j = 0; j < 16; j++)
         {
             int num  = TerrainChunk.CalculateCellIndex(i, 255, j);
             int num2 = 0;
             int num3 = 255;
             while (num3 >= 0)
             {
                 int cellValueFast = chunk.GetCellValueFast(num);
                 int num4          = Terrain.ExtractContents(cellValueFast);
                 if (num4 != 0 && num4 != num2 && BlocksManager.Blocks[num4] is FluidBlock)
                 {
                     int data = Terrain.ExtractData(cellValueFast);
                     chunk.SetCellValueFast(num, Terrain.MakeBlockValue(num4, 0, FluidBlock.SetIsTop(data, isTop: true)));
                 }
                 num2 = num4;
                 num3--;
                 num--;
             }
         }
     }
 }
Пример #4
0
        public TerrainChunk GetNextChunk(int chunkX, int chunkZ)
        {
            TerrainChunk terrainChunk = GetChunkAtCoords(chunkX, chunkZ);

            if (terrainChunk != null)
            {
                return(terrainChunk);
            }
            TerrainChunk[] allocatedChunks = AllocatedChunks;
            for (int i = 0; i < allocatedChunks.Length; i++)
            {
                if (ComparePoints(allocatedChunks[i].Coords, new Point2(chunkX, chunkZ)) >= 0 && (terrainChunk == null || ComparePoints(allocatedChunks[i].Coords, terrainChunk.Coords) < 0))
                {
                    terrainChunk = allocatedChunks[i];
                }
            }
            if (terrainChunk == null)
            {
                for (int j = 0; j < allocatedChunks.Length; j++)
                {
                    if (terrainChunk == null || ComparePoints(allocatedChunks[j].Coords, terrainChunk.Coords) < 0)
                    {
                        terrainChunk = allocatedChunks[j];
                    }
                }
            }
            return(terrainChunk);
        }
Пример #5
0
        public void PaintFastAvoidWater(TerrainChunk chunk, int x, int y, int z)
        {
            Terrain terrain = chunk.Terrain;

            x -= chunk.Origin.X;
            z -= chunk.Origin.Y;
            Cell[] cells = Cells;
            for (int i = 0; i < cells.Length; i++)
            {
                Cell cell = cells[i];
                int  num  = cell.X + x;
                int  num2 = cell.Y + y;
                int  num3 = cell.Z + z;
                if (num >= 0 && num < 16 && num2 >= 0 && num2 < 255 && num3 >= 0 && num3 < 16)
                {
                    int num4 = num + chunk.Origin.X;
                    int y2   = num2;
                    int num5 = num3 + chunk.Origin.Y;
                    if (chunk.GetCellContentsFast(num, num2, num3) != 18 && terrain.GetCellContents(num4 - 1, y2, num5) != 18 && terrain.GetCellContents(num4 + 1, y2, num5) != 18 && terrain.GetCellContents(num4, y2, num5 - 1) != 18 && terrain.GetCellContents(num4, y2, num5 + 1) != 18 && chunk.GetCellContentsFast(num, num2 + 1, num3) != 18)
                    {
                        chunk.SetCellValueFast(num, num2, num3, cell.Value);
                    }
                }
            }
        }
Пример #6
0
        public void DrawTransparent(Camera camera)
        {
            int     gameWidgetIndex = camera.GameWidget.GameWidgetIndex;
            Vector3 viewPosition    = camera.ViewPosition;
            Vector3 v     = new Vector3(MathUtils.Floor(viewPosition.X), 0f, MathUtils.Floor(viewPosition.Z));
            Matrix  value = Matrix.CreateTranslation(v - viewPosition) * camera.ViewMatrix.OrientationMatrix * camera.ProjectionMatrix;

            Display.BlendState        = BlendState.AlphaBlend;
            Display.DepthStencilState = DepthStencilState.Default;
            Display.RasterizerState   = ((m_subsystemSky.ViewUnderWaterDepth > 0f) ? RasterizerState.CullClockwiseScissor : RasterizerState.CullCounterClockwiseScissor);
            m_transparentShader.GetParameter("u_origin").SetValue(v.XZ);
            m_transparentShader.GetParameter("u_viewProjectionMatrix").SetValue(value);
            m_transparentShader.GetParameter("u_viewPosition").SetValue(viewPosition);
            m_transparentShader.GetParameter("u_texture").SetValue(m_subsystemAnimatedTextures.AnimatedBlocksTexture);
            m_transparentShader.GetParameter("u_samplerState").SetValue(SettingsManager.TerrainMipmapsEnabled ? m_samplerStateMips : m_samplerState);
            m_transparentShader.GetParameter("u_fogYMultiplier").SetValue(m_subsystemSky.VisibilityRangeYMultiplier);
            m_transparentShader.GetParameter("u_fogColor").SetValue(new Vector3(m_subsystemSky.ViewFogColor));
            ShaderParameter parameter = m_transparentShader.GetParameter("u_fogStartInvLength");

            for (int i = 0; i < m_chunksToDraw.Count; i++)
            {
                TerrainChunk terrainChunk = m_chunksToDraw[i];
                float        num          = MathUtils.Min(terrainChunk.FogEnds[gameWidgetIndex], m_subsystemSky.ViewFogRange.Y);
                float        num2         = MathUtils.Min(m_subsystemSky.ViewFogRange.X, num - 1f);
                parameter.SetValue(new Vector2(num2, 1f / (num - num2)));
                int subsetsMask = 64;
                DrawTerrainChunkGeometrySubsets(m_transparentShader, terrainChunk.Geometry, subsetsMask);
            }
        }
Пример #7
0
        public void SimulateThermometer(int x, int y, int z, bool invalidateTerrainOnChange)
        {
            Point3 key = new Point3(x, y, z);

            if (!m_thermometersByPoint.ContainsKey(key))
            {
                return;
            }
            int num = m_thermometersByPoint[key];

            CalculateTemperature(x, y, z, 0f, 0f, out float temperature, out float _);
            int num2 = MathUtils.Clamp((int)MathUtils.Round(temperature), 0, 15);

            if (num2 == num)
            {
                return;
            }
            m_thermometersByPoint[new Point3(x, y, z)] = num2;
            if (invalidateTerrainOnChange)
            {
                TerrainChunk chunkAtCell = base.SubsystemTerrain.Terrain.GetChunkAtCell(x, z);
                if (chunkAtCell != null)
                {
                    base.SubsystemTerrain.TerrainUpdater.DowngradeChunkNeighborhoodState(chunkAtCell.Coords, 0, TerrainChunkState.InvalidVertices1, forceGeometryRegeneration: true);
                }
            }
        }
Пример #8
0
 public float?GetSurfaceHeight(int x, int y, int z, out FluidBlock surfaceFluidBlock)
 {
     if (y >= 0 && y < 255)
     {
         TerrainChunk chunkAtCell = base.SubsystemTerrain.Terrain.GetChunkAtCell(x, z);
         if (chunkAtCell != null)
         {
             int num = TerrainChunk.CalculateCellIndex(x & 0xF, 0, z & 0xF);
             while (y < 255)
             {
                 int num2 = Terrain.ExtractContents(chunkAtCell.GetCellValueFast(num + y + 1));
                 if (BlocksManager.FluidBlocks[num2] == null)
                 {
                     int        cellValueFast = chunkAtCell.GetCellValueFast(num + y);
                     int        num3          = Terrain.ExtractContents(cellValueFast);
                     FluidBlock fluidBlock    = BlocksManager.FluidBlocks[num3];
                     if (fluidBlock != null)
                     {
                         surfaceFluidBlock = fluidBlock;
                         int level = FluidBlock.GetLevel(Terrain.ExtractData(cellValueFast));
                         return((float)y + surfaceFluidBlock.GetLevelHeight(level));
                     }
                     surfaceFluidBlock = null;
                     return(null);
                 }
                 y++;
             }
         }
     }
     surfaceFluidBlock = null;
     return(null);
 }
Пример #9
0
 public void DrawSigns(Camera camera)
 {
     if (m_nearTexts.Count > 0)
     {
         TexturedBatch3D texturedBatch3D = m_primitivesRenderer3D.TexturedBatch(m_renderTarget, useAlphaTest: false, 0, DepthStencilState.DepthRead, RasterizerState.CullCounterClockwiseScissor, null, SamplerState.PointClamp);
         foreach (TextData nearText in m_nearTexts)
         {
             if (nearText.TextureLocation.HasValue)
             {
                 int       cellValue = m_subsystemTerrain.Terrain.GetCellValue(nearText.Point.X, nearText.Point.Y, nearText.Point.Z);
                 int       num       = Terrain.ExtractContents(cellValue);
                 SignBlock signBlock = BlocksManager.Blocks[num] as SignBlock;
                 if (signBlock != null)
                 {
                     int       data = Terrain.ExtractData(cellValue);
                     BlockMesh signSurfaceBlockMesh = signBlock.GetSignSurfaceBlockMesh(data);
                     if (signSurfaceBlockMesh != null)
                     {
                         TerrainChunk chunkAtCell = m_subsystemTerrain.Terrain.GetChunkAtCell(nearText.Point.X, nearText.Point.Z);
                         if (chunkAtCell != null && chunkAtCell.State >= TerrainChunkState.InvalidVertices1)
                         {
                             nearText.Light = Terrain.ExtractLight(cellValue);
                         }
                         float   num2              = LightingManager.LightIntensityByLightValue[nearText.Light];
                         Color   color             = new Color(num2, num2, num2);
                         float   x                 = 0f;
                         float   x2                = nearText.UsedTextureWidth / 128f;
                         float   x3                = (float)nearText.TextureLocation.Value / 32f;
                         float   x4                = ((float)nearText.TextureLocation.Value + nearText.UsedTextureHeight / 32f) / 32f;
                         Vector3 signSurfaceNormal = signBlock.GetSignSurfaceNormal(data);
                         Vector3 vector            = new Vector3(nearText.Point.X, nearText.Point.Y, nearText.Point.Z);
                         float   num3              = Vector3.Dot(camera.ViewPosition - (vector + new Vector3(0.5f)), signSurfaceNormal);
                         Vector3 v                 = MathUtils.Max(0.01f * num3, 0.005f) * signSurfaceNormal;
                         for (int i = 0; i < signSurfaceBlockMesh.Indices.Count / 3; i++)
                         {
                             BlockMeshVertex blockMeshVertex  = signSurfaceBlockMesh.Vertices.Array[signSurfaceBlockMesh.Indices.Array[i * 3]];
                             BlockMeshVertex blockMeshVertex2 = signSurfaceBlockMesh.Vertices.Array[signSurfaceBlockMesh.Indices.Array[i * 3 + 1]];
                             BlockMeshVertex blockMeshVertex3 = signSurfaceBlockMesh.Vertices.Array[signSurfaceBlockMesh.Indices.Array[i * 3 + 2]];
                             Vector3         p  = blockMeshVertex.Position + vector + v;
                             Vector3         p2 = blockMeshVertex2.Position + vector + v;
                             Vector3         p3 = blockMeshVertex3.Position + vector + v;
                             Vector2         textureCoordinates  = blockMeshVertex.TextureCoordinates;
                             Vector2         textureCoordinates2 = blockMeshVertex2.TextureCoordinates;
                             Vector2         textureCoordinates3 = blockMeshVertex3.TextureCoordinates;
                             textureCoordinates.X  = MathUtils.Lerp(x, x2, textureCoordinates.X);
                             textureCoordinates2.X = MathUtils.Lerp(x, x2, textureCoordinates2.X);
                             textureCoordinates3.X = MathUtils.Lerp(x, x2, textureCoordinates3.X);
                             textureCoordinates.Y  = MathUtils.Lerp(x3, x4, textureCoordinates.Y);
                             textureCoordinates2.Y = MathUtils.Lerp(x3, x4, textureCoordinates2.Y);
                             textureCoordinates3.Y = MathUtils.Lerp(x3, x4, textureCoordinates3.Y);
                             texturedBatch3D.QueueTriangle(p, p2, p3, textureCoordinates, textureCoordinates2, textureCoordinates3, color);
                         }
                     }
                 }
             }
         }
         m_primitivesRenderer3D.Flush(camera.ViewProjectionMatrix);
     }
 }
Пример #10
0
 public void RunChunkFadeIn(Camera camera, TerrainChunk chunk)
 {
     chunk.FogEnds[camera.GameWidget.GameWidgetIndex] += 32f * Time.FrameDuration;
     if (chunk.FogEnds[camera.GameWidget.GameWidgetIndex] >= m_subsystemSky.ViewFogRange.Y)
     {
         chunk.FogEnds[camera.GameWidget.GameWidgetIndex] = float.MaxValue;
     }
 }
Пример #11
0
 public void SaveChunk(TerrainChunk chunk)
 {
     if (chunk.State > TerrainChunkState.InvalidContents4 && chunk.ModificationCounter > 0)
     {
         SaveChunkBlocks(chunk);
         chunk.ModificationCounter = 0;
     }
 }
Пример #12
0
        public float?CalculateDistanceToFluid(Vector3 p, int radius, bool flowingFluidOnly)
        {
            float   num     = float.MaxValue;
            Terrain terrain = base.SubsystemTerrain.Terrain;
            int     num2    = Terrain.ToCell(p.X) - radius;
            int     num3    = Terrain.ToCell(p.X) + radius;
            int     num4    = MathUtils.Clamp(Terrain.ToCell(p.Y) - radius, 0, 254);
            int     num5    = MathUtils.Clamp(Terrain.ToCell(p.Y) + radius, 0, 254);
            int     num6    = Terrain.ToCell(p.Z) - radius;
            int     num7    = Terrain.ToCell(p.Z) + radius;

            for (int i = num6; i <= num7; i++)
            {
                for (int j = num2; j <= num3; j++)
                {
                    TerrainChunk chunkAtCell = terrain.GetChunkAtCell(j, i);
                    if (chunkAtCell == null)
                    {
                        continue;
                    }
                    int k = TerrainChunk.CalculateCellIndex(j & 0xF, num4, i & 0xF);
                    for (int l = num4; l <= num5; l++, k++)
                    {
                        int cellValueFast = chunkAtCell.GetCellValueFast(k);
                        int contents      = Terrain.ExtractContents(cellValueFast);
                        if (!m_fluidBlock.IsTheSameFluid(contents))
                        {
                            continue;
                        }
                        if (flowingFluidOnly)
                        {
                            if (FluidBlock.GetLevel(Terrain.ExtractData(cellValueFast)) == 0)
                            {
                                continue;
                            }
                            int contents2 = Terrain.ExtractContents(chunkAtCell.GetCellValueFast(k + 1));
                            if (m_fluidBlock.IsTheSameFluid(contents2))
                            {
                                continue;
                            }
                        }
                        float num8  = p.X - ((float)j + 0.5f);
                        float num9  = p.Y - ((float)l + 1f);
                        float num10 = p.Z - ((float)i + 0.5f);
                        float num11 = num8 * num8 + num9 * num9 + num10 * num10;
                        if (num11 < num)
                        {
                            num = num11;
                        }
                    }
                }
            }
            if (num == float.MaxValue)
            {
                return(null);
            }
            return(MathUtils.Sqrt(num));
        }
Пример #13
0
        public void FreezeThawAndDepositSnow(TerrainChunk chunk)
        {
            Terrain terrain = SubsystemTerrain.Terrain;

            for (int i = 0; i < 16; i++)
            {
                for (int j = 0; j < 16; j++)
                {
                    if (m_random.Int() % 2 == 0)
                    {
                        continue;
                    }
                    int topHeightFast = chunk.GetTopHeightFast(i, j);
                    int cellValueFast = chunk.GetCellValueFast(i, topHeightFast, j);
                    int num           = Terrain.ExtractContents(cellValueFast);
                    int num2          = chunk.Origin.X + i;
                    int num3          = topHeightFast;
                    int num4          = chunk.Origin.Y + j;
                    PrecipitationShaftInfo precipitationShaftInfo = GetPrecipitationShaftInfo(num2, num4);
                    if (precipitationShaftInfo.Type == PrecipitationType.Snow)
                    {
                        if (num == 18)
                        {
                            int  cellContents  = terrain.GetCellContents(num2 + 1, num3, num4);
                            int  cellContents2 = terrain.GetCellContents(num2 - 1, num3, num4);
                            int  cellContents3 = terrain.GetCellContents(num2, num3, num4 - 1);
                            int  cellContents4 = terrain.GetCellContents(num2, num3, num4 + 1);
                            bool num5          = cellContents != 18 && cellContents != 0;
                            bool flag          = cellContents2 != 18 && cellContents2 != 0;
                            bool flag2         = cellContents3 != 18 && cellContents3 != 0;
                            bool flag3         = cellContents4 != 18 && cellContents4 != 0;
                            if (num5 | flag | flag2 | flag3)
                            {
                                SubsystemTerrain.ChangeCell(num2, num3, num4, Terrain.MakeBlockValue(62));
                            }
                        }
                        else if (precipitationShaftInfo.Intensity > 0.5f && SubsystemSnowBlockBehavior.CanSupportSnow(cellValueFast) && (num != 62 || ShaftHasSnowOnIce(num2, num4)) && num3 + 1 < 255)
                        {
                            SubsystemTerrain.ChangeCell(num2, num3 + 1, num4, Terrain.MakeBlockValue(61));
                        }
                    }
                    else
                    {
                        switch (num)
                        {
                        case 61:
                            SubsystemTerrain.DestroyCell(0, num2, num3, num4, 0, noDrop: true, noParticleSystem: true);
                            break;

                        case 62:
                            SubsystemTerrain.DestroyCell(0, num2, num3, num4, 0, noDrop: false, noParticleSystem: true);
                            break;
                        }
                    }
                }
            }
        }
Пример #14
0
 public void FreeChunk(TerrainChunk chunk)
 {
     if (!m_allocatedChunks.Remove(chunk))
     {
         throw new InvalidOperationException("Chunk not allocated.");
     }
     m_allChunks.Remove(chunk.Coords.X, chunk.Coords.Y);
     m_allocatedChunksArray = null;
 }
Пример #15
0
 public void OnChunkDiscarding(TerrainChunk chunk)
 {
     foreach (CellFace key in m_electricElementsByCellFace.Keys)
     {
         if (key.X >= chunk.Origin.X && key.X < chunk.Origin.X + 16 && key.Z >= chunk.Origin.Y && key.Z < chunk.Origin.Y + 16)
         {
             m_pointsToUpdate[new Point3(key.X, key.Y, key.Z)] = false;
         }
     }
 }
Пример #16
0
            public void Add(int x, int y, TerrainChunk chunk)
            {
                int num = (x + (y << 8)) & 0xFFFF;

                while (m_array[num] != null)
                {
                    num = ((num + 1) & 0xFFFF);
                }
                m_array[num] = chunk;
            }
Пример #17
0
 public void ProcessQueuedActions()
 {
     m_tmpActions.Clear();
     m_tmpActions.AddRange(m_actions);
     foreach (KeyValuePair <Point3, QueuedAction> tmpAction in m_tmpActions)
     {
         Point3       key   = tmpAction.Key;
         QueuedAction value = tmpAction.Value;
         if (Terrain.ExtractContents(m_subsystemTerrain.Terrain.GetCellValue(key.X, key.Y, key.Z)) != 237)
         {
             StopPiston(key);
             value.Move = null;
             value.Stop = false;
         }
         else if (value.Stop)
         {
             StopPiston(key);
             value.Stop         = false;
             value.StoppedFrame = Time.FrameIndex;
         }
     }
     foreach (KeyValuePair <Point3, QueuedAction> tmpAction2 in m_tmpActions)
     {
         Point3       key2   = tmpAction2.Key;
         QueuedAction value2 = tmpAction2.Value;
         if (value2.Move.HasValue && !value2.Stop && Time.FrameIndex != value2.StoppedFrame && m_subsystemMovingBlocks.FindMovingBlocks("Piston", key2) == null)
         {
             bool flag = true;
             for (int i = -1; i <= 1; i++)
             {
                 for (int j = -1; j <= 1; j++)
                 {
                     TerrainChunk chunkAtCell = m_subsystemTerrain.Terrain.GetChunkAtCell(key2.X + i * 16, key2.Z + j * 16);
                     if (chunkAtCell == null || chunkAtCell.State <= TerrainChunkState.InvalidContents4)
                     {
                         flag = false;
                     }
                 }
             }
             if (flag && MovePiston(key2, value2.Move.Value))
             {
                 value2.Move = null;
             }
         }
     }
     foreach (KeyValuePair <Point3, QueuedAction> tmpAction3 in m_tmpActions)
     {
         Point3       key3   = tmpAction3.Key;
         QueuedAction value3 = tmpAction3.Value;
         if (!value3.Move.HasValue && !value3.Stop)
         {
             m_actions.Remove(key3);
         }
     }
 }
Пример #18
0
        public bool LoadChunkBlocks(TerrainChunk chunk)
        {
            _ = Time.RealTime;
            bool    result  = false;
            Terrain terrain = m_subsystemTerrain.Terrain;
            int     num     = chunk.Origin.X >> 4;
            int     num2    = chunk.Origin.Y >> 4;

            try
            {
                if (m_chunkOffsets.TryGetValue(new Point2(num, num2), out int value))
                {
                    m_stream.Seek(value, SeekOrigin.Begin);
                    ReadChunkHeader(m_stream);
                    int num3 = 0;
                    m_stream.Read(m_buffer, 0, 131072);
                    for (int i = 0; i < 16; i++)
                    {
                        for (int j = 0; j < 16; j++)
                        {
                            int num4 = TerrainChunk.CalculateCellIndex(i, 0, j);
                            for (int k = 0; k < 256; k++)
                            {
                                int num5 = m_buffer[num3++];
                                num5 |= m_buffer[num3++] << 8;
                                chunk.SetCellValueFast(num4++, num5);
                            }
                        }
                    }
                    num3 = 0;
                    m_stream.Read(m_buffer, 0, 1024);
                    for (int l = 0; l < 16; l++)
                    {
                        for (int m = 0; m < 16; m++)
                        {
                            int num6 = m_buffer[num3++];
                            num6 |= m_buffer[num3++] << 8;
                            num6 |= m_buffer[num3++] << 16;
                            num6 |= m_buffer[num3++] << 24;
                            terrain.SetShaftValue(l + chunk.Origin.X, m + chunk.Origin.Y, num6);
                        }
                    }
                    result = true;
                }
            }
            catch (Exception e)
            {
                Log.Error(ExceptionManager.MakeFullErrorMessage($"Error loading data for chunk ({num},{num2}).", e));
            }
            _ = Time.RealTime;
            return(result);
        }
Пример #19
0
            public bool IsBlocked(BoundingBox box)
            {
                int num  = Terrain.ToCell(box.Min.X);
                int num2 = MathUtils.Max(Terrain.ToCell(box.Min.Y), 0);
                int num3 = Terrain.ToCell(box.Min.Z);
                int num4 = Terrain.ToCell(box.Max.X);
                int num5 = MathUtils.Min(Terrain.ToCell(box.Max.Y), 255);
                int num6 = Terrain.ToCell(box.Max.Z);

                for (int i = num; i <= num4; i++)
                {
                    for (int j = num3; j <= num6; j++)
                    {
                        TerrainChunk chunkAtCell = SubsystemTerrain.Terrain.GetChunkAtCell(i, j);
                        if (chunkAtCell == null)
                        {
                            continue;
                        }
                        int num7 = TerrainChunk.CalculateCellIndex(i & 0xF, num2, j & 0xF);
                        int num8 = num2;
                        while (num8 <= num5)
                        {
                            int cellValueFast = chunkAtCell.GetCellValueFast(num7);
                            int num9          = Terrain.ExtractContents(cellValueFast);
                            if (num9 != 0)
                            {
                                Block block = BlocksManager.Blocks[num9];
                                if (block.ShouldAvoid(cellValueFast))
                                {
                                    return(true);
                                }
                                if (block.IsCollidable)
                                {
                                    Vector3       v = new Vector3(i, num8, j);
                                    BoundingBox[] customCollisionBoxes = block.GetCustomCollisionBoxes(SubsystemTerrain, cellValueFast);
                                    for (int k = 0; k < customCollisionBoxes.Length; k++)
                                    {
                                        BoundingBox boundingBox = customCollisionBoxes[k];
                                        if (box.Intersection(new BoundingBox(v + boundingBox.Min, v + boundingBox.Max)))
                                        {
                                            return(true);
                                        }
                                    }
                                }
                            }
                            num8++;
                            num7++;
                        }
                    }
                }
                return(false);
            }
Пример #20
0
        public TerrainChunk AllocateChunk(int chunkX, int chunkZ)
        {
            if (GetChunkAtCoords(chunkX, chunkZ) != null)
            {
                throw new InvalidOperationException("Chunk already allocated.");
            }
            TerrainChunk terrainChunk = new TerrainChunk(this, chunkX, chunkZ);

            m_allocatedChunks.Add(terrainChunk);
            m_allChunks.Add(chunkX, chunkZ, terrainChunk);
            m_allocatedChunksArray = null;
            return(terrainChunk);
        }
Пример #21
0
        public void ChangeCell(int x, int y, int z, int value, bool updateModificationCounter = true)
        {
            if (!Terrain.IsCellValid(x, y, z))
            {
                return;
            }
            int cellValueFast = Terrain.GetCellValueFast(x, y, z);

            value         = Terrain.ReplaceLight(value, 0);
            cellValueFast = Terrain.ReplaceLight(cellValueFast, 0);
            if (value == cellValueFast)
            {
                return;
            }
            Terrain.SetCellValueFast(x, y, z, value);
            TerrainChunk chunkAtCell = Terrain.GetChunkAtCell(x, z);

            if (chunkAtCell != null)
            {
                if (updateModificationCounter)
                {
                    chunkAtCell.ModificationCounter++;
                }
                TerrainUpdater.DowngradeChunkNeighborhoodState(chunkAtCell.Coords, 1, TerrainChunkState.InvalidLight, forceGeometryRegeneration: false);
            }
            m_modifiedCells[new Point3(x, y, z)] = true;
            int num  = Terrain.ExtractContents(cellValueFast);
            int num2 = Terrain.ExtractContents(value);

            if (num2 != num)
            {
                SubsystemBlockBehavior[] blockBehaviors = m_subsystemBlockBehaviors.GetBlockBehaviors(num);
                for (int i = 0; i < blockBehaviors.Length; i++)
                {
                    blockBehaviors[i].OnBlockRemoved(cellValueFast, value, x, y, z);
                }
                SubsystemBlockBehavior[] blockBehaviors2 = m_subsystemBlockBehaviors.GetBlockBehaviors(num2);
                for (int j = 0; j < blockBehaviors2.Length; j++)
                {
                    blockBehaviors2[j].OnBlockAdded(value, cellValueFast, x, y, z);
                }
            }
            else
            {
                SubsystemBlockBehavior[] blockBehaviors3 = m_subsystemBlockBehaviors.GetBlockBehaviors(num2);
                for (int k = 0; k < blockBehaviors3.Length; k++)
                {
                    blockBehaviors3[k].OnBlockModified(value, cellValueFast, x, y, z);
                }
            }
        }
Пример #22
0
        public override void OnChunkDiscarding(TerrainChunk chunk)
        {
            BoundingBox boundingBox = new BoundingBox(chunk.BoundingBox.Min - new Vector3(16f), chunk.BoundingBox.Max + new Vector3(16f));
            DynamicArray <IMovingBlockSet> dynamicArray = new DynamicArray <IMovingBlockSet>();

            m_subsystemMovingBlocks.FindMovingBlocks(boundingBox, extendToFillCells: false, dynamicArray);
            foreach (IMovingBlockSet item in dynamicArray)
            {
                if (item.Id == "Piston")
                {
                    StopPiston((Point3)item.Tag);
                }
            }
        }
Пример #23
0
        public void StartChunkFadeIn(Camera camera, TerrainChunk chunk)
        {
            Vector3 viewPosition = camera.ViewPosition;
            Vector2 v            = new Vector2(chunk.Origin.X, chunk.Origin.Y);
            Vector2 v2           = new Vector2(chunk.Origin.X + 16, chunk.Origin.Y);
            Vector2 v3           = new Vector2(chunk.Origin.X, chunk.Origin.Y + 16);
            Vector2 v4           = new Vector2(chunk.Origin.X + 16, chunk.Origin.Y + 16);
            float   x            = Vector2.Distance(viewPosition.XZ, v);
            float   x2           = Vector2.Distance(viewPosition.XZ, v2);
            float   x3           = Vector2.Distance(viewPosition.XZ, v3);
            float   x4           = Vector2.Distance(viewPosition.XZ, v4);

            chunk.FogEnds[camera.GameWidget.GameWidgetIndex] = MathUtils.Max(MathUtils.Min(x, x2, x3, x4), 0.001f);
        }
Пример #24
0
        public void FindTerrainCollisionBoxes(BoundingBox box, DynamicArray <CollisionBox> result)
        {
            Point3 point  = Terrain.ToCell(box.Min);
            Point3 point2 = Terrain.ToCell(box.Max);

            point.Y  = MathUtils.Max(point.Y, 0);
            point2.Y = MathUtils.Min(point2.Y, 255);
            if (point.Y > point2.Y)
            {
                return;
            }
            for (int i = point.X; i <= point2.X; i++)
            {
                for (int j = point.Z; j <= point2.Z; j++)
                {
                    TerrainChunk chunkAtCell = m_subsystemTerrain.Terrain.GetChunkAtCell(i, j);
                    if (chunkAtCell == null)
                    {
                        continue;
                    }
                    int num  = TerrainChunk.CalculateCellIndex(i & 0xF, point.Y, j & 0xF);
                    int num2 = point.Y;
                    while (num2 <= point2.Y)
                    {
                        int cellValueFast = chunkAtCell.GetCellValueFast(num);
                        int num3          = Terrain.ExtractContents(cellValueFast);
                        if (num3 != 0)
                        {
                            Block block = BlocksManager.Blocks[num3];
                            if (block.IsCollidable)
                            {
                                BoundingBox[] customCollisionBoxes = block.GetCustomCollisionBoxes(m_subsystemTerrain, cellValueFast);
                                Vector3       v = new Vector3(i, num2, j);
                                for (int k = 0; k < customCollisionBoxes.Length; k++)
                                {
                                    result.Add(new CollisionBox
                                    {
                                        Box        = new BoundingBox(v + customCollisionBoxes[k].Min, v + customCollisionBoxes[k].Max),
                                        BlockValue = cellValueFast
                                    });
                                }
                            }
                        }
                        num2++;
                        num++;
                    }
                }
            }
        }
Пример #25
0
        public void ScanWireDomain(CellFace startCellFace, Dictionary <CellFace, bool> visited, Dictionary <CellFace, bool> result)
        {
            DynamicArray <CellFace> dynamicArray = new DynamicArray <CellFace>();

            dynamicArray.Add(startCellFace);
            while (dynamicArray.Count > 0)
            {
                CellFace key = dynamicArray.Array[--dynamicArray.Count];
                if (visited.ContainsKey(key))
                {
                    continue;
                }
                TerrainChunk chunkAtCell = SubsystemTerrain.Terrain.GetChunkAtCell(key.X, key.Z);
                if (chunkAtCell == null || !chunkAtCell.AreBehaviorsNotified)
                {
                    continue;
                }
                int cellValue = SubsystemTerrain.Terrain.GetCellValue(key.X, key.Y, key.Z);
                int num       = Terrain.ExtractContents(cellValue);
                IElectricWireElementBlock electricWireElementBlock = BlocksManager.Blocks[num] as IElectricWireElementBlock;
                if (electricWireElementBlock == null)
                {
                    continue;
                }
                int connectedWireFacesMask = electricWireElementBlock.GetConnectedWireFacesMask(cellValue, key.Face);
                if (connectedWireFacesMask == 0)
                {
                    continue;
                }
                for (int i = 0; i < 6; i++)
                {
                    if ((connectedWireFacesMask & (1 << i)) != 0)
                    {
                        CellFace key2 = new CellFace(key.X, key.Y, key.Z, i);
                        visited.Add(key2, value: true);
                        result.Add(key2, value: true);
                        m_tmpConnectionPaths.Clear();
                        GetAllConnectedNeighbors(key2.X, key2.Y, key2.Z, key2.Face, m_tmpConnectionPaths);
                        foreach (ElectricConnectionPath tmpConnectionPath in m_tmpConnectionPaths)
                        {
                            int x = key2.X + tmpConnectionPath.NeighborOffsetX;
                            int y = key2.Y + tmpConnectionPath.NeighborOffsetY;
                            int z = key2.Z + tmpConnectionPath.NeighborOffsetZ;
                            dynamicArray.Add(new CellFace(x, y, z, tmpConnectionPath.NeighborFace));
                        }
                    }
                }
            }
        }
Пример #26
0
        public void Draw(Camera camera, int drawOrder)
        {
            double totalElapsedGameTime = m_subsystemGameInfo.TotalElapsedGameTime;

            m_drawBlockEnvironmentData.SubsystemTerrain = m_subsystemTerrain;
            Matrix matrix = Matrix.CreateRotationY((float)MathUtils.Remainder(totalElapsedGameTime, 6.2831854820251465));
            float  num    = MathUtils.Min(m_subsystemSky.VisibilityRange, 30f);

            foreach (Pickable pickable in m_pickables)
            {
                Vector3 position = pickable.Position;
                float   num2     = Vector3.Dot(camera.ViewDirection, position - camera.ViewPosition);
                if (num2 > -0.5f && num2 < num)
                {
                    int   num3  = Terrain.ExtractContents(pickable.Value);
                    Block block = BlocksManager.Blocks[num3];
                    float num4  = (float)(totalElapsedGameTime - pickable.CreationTime);
                    if (!pickable.StuckMatrix.HasValue)
                    {
                        position.Y += 0.25f * MathUtils.Saturate(3f * num4);
                    }
                    int          x           = Terrain.ToCell(position.X);
                    int          num5        = Terrain.ToCell(position.Y);
                    int          z           = Terrain.ToCell(position.Z);
                    TerrainChunk chunkAtCell = m_subsystemTerrain.Terrain.GetChunkAtCell(x, z);
                    if (chunkAtCell != null && chunkAtCell.State >= TerrainChunkState.InvalidVertices1 && num5 >= 0 && num5 < 255)
                    {
                        m_drawBlockEnvironmentData.Humidity    = m_subsystemTerrain.Terrain.GetSeasonalHumidity(x, z);
                        m_drawBlockEnvironmentData.Temperature = m_subsystemTerrain.Terrain.GetSeasonalTemperature(x, z) + SubsystemWeather.GetTemperatureAdjustmentAtHeight(num5);
                        float f    = MathUtils.Max(position.Y - (float)num5 - 0.75f, 0f) / 0.25f;
                        int   num6 = pickable.Light = (int)MathUtils.Lerp(m_subsystemTerrain.Terrain.GetCellLightFast(x, num5, z), m_subsystemTerrain.Terrain.GetCellLightFast(x, num5 + 1, z), f);
                    }
                    m_drawBlockEnvironmentData.Light = pickable.Light;
                    m_drawBlockEnvironmentData.BillboardDirection        = pickable.Position - camera.ViewPosition;
                    m_drawBlockEnvironmentData.InWorldMatrix.Translation = position;
                    if (pickable.StuckMatrix.HasValue)
                    {
                        Matrix matrix2 = pickable.StuckMatrix.Value;
                        block.DrawBlock(m_primitivesRenderer, pickable.Value, Color.White, 0.3f, ref matrix2, m_drawBlockEnvironmentData);
                    }
                    else
                    {
                        matrix.Translation = position + new Vector3(0f, 0.04f * MathUtils.Sin(3f * num4), 0f);
                        block.DrawBlock(m_primitivesRenderer, pickable.Value, Color.White, 0.3f, ref matrix, m_drawBlockEnvironmentData);
                    }
                }
            }
            m_primitivesRenderer.Flush(camera.ViewProjectionMatrix);
        }
Пример #27
0
        public override void OnChunkDiscarding(TerrainChunk chunk)
        {
            List <Point3> list = new List <Point3>();

            foreach (Point3 key in m_particleSystemsByCell.Keys)
            {
                if (key.X >= chunk.Origin.X && key.X < chunk.Origin.X + 16 && key.Z >= chunk.Origin.Y && key.Z < chunk.Origin.Y + 16)
                {
                    list.Add(key);
                }
            }
            foreach (Point3 item in list)
            {
                RemoveParticleSystems(item.X, item.Y, item.Z);
            }
        }
        public override void OnChunkDiscarding(TerrainChunk chunk)
        {
            List <Point3> list = new List <Point3>();

            foreach (Point3 key in m_explosiveDataByPoint.Keys)
            {
                if (key.X >= chunk.Origin.X && key.X < chunk.Origin.X + 16 && key.Z >= chunk.Origin.Y && key.Z < chunk.Origin.Y + 16)
                {
                    list.Add(key);
                }
            }
            foreach (Point3 item in list)
            {
                RemoveExplosive(item);
            }
        }
 public void GenerateChunkContentsPass1(TerrainChunk chunk)
 {
     for (int i = 0; i < 16; i++)
     {
         for (int j = 0; j < 16; j++)
         {
             int num  = i + chunk.Origin.X;
             int num2 = j + chunk.Origin.Y;
             chunk.SetTemperatureFast(i, j, CalculateTemperature(num, num2));
             chunk.SetHumidityFast(i, j, CalculateHumidity(num, num2));
             bool flag = CalculateOceanShoreDistance(num, num2) >= 0f;
             int  num3 = TerrainChunk.CalculateCellIndex(i, 0, j);
             for (int k = 0; k < 256; k++)
             {
                 int value = Terrain.MakeBlockValue(0);
                 if (flag)
                 {
                     if (k < 2)
                     {
                         value = Terrain.MakeBlockValue(1);
                     }
                     else if (k < m_worldSettings.TerrainLevel)
                     {
                         value = Terrain.MakeBlockValue((m_worldSettings.TerrainBlockIndex == 8) ? 2 : m_worldSettings.TerrainBlockIndex);
                     }
                     else if (k == m_worldSettings.TerrainLevel)
                     {
                         value = Terrain.MakeBlockValue(m_worldSettings.TerrainBlockIndex);
                     }
                     else if (k <= OceanLevel)
                     {
                         value = Terrain.MakeBlockValue(m_worldSettings.TerrainOceanBlockIndex);
                     }
                 }
                 else if (k < 2)
                 {
                     value = Terrain.MakeBlockValue(1);
                 }
                 else if (k <= OceanLevel)
                 {
                     value = Terrain.MakeBlockValue(m_worldSettings.TerrainOceanBlockIndex);
                 }
                 chunk.SetCellValueFast(num3 + k, value);
             }
         }
     }
 }
Пример #30
0
        public void DecayLeavesIfNeeded(Point3 p)
        {
            m_leavesToCheck.Remove(p);
            if (!(BlocksManager.Blocks[base.SubsystemTerrain.Terrain.GetCellContents(p.X, p.Y, p.Z)] is LeavesBlock))
            {
                return;
            }
            bool flag = false;
            int  num  = p.X - 3;
            int  num2 = MathUtils.Max(p.Y - 3, 0);
            int  num3 = p.Z - 3;
            int  num4 = p.X + 3;
            int  num5 = MathUtils.Min(p.Y + 3, 255);
            int  num6 = p.Z + 3;

            for (int i = num; i <= num4; i++)
            {
                for (int j = num3; j <= num6; j++)
                {
                    TerrainChunk chunkAtCell = base.SubsystemTerrain.Terrain.GetChunkAtCell(i, j);
                    if (chunkAtCell == null)
                    {
                        continue;
                    }
                    int num7 = TerrainChunk.CalculateCellIndex(i & 0xF, 0, j & 0xF);
                    int num8 = num2;
                    while (num8 <= num5)
                    {
                        int num9 = Terrain.ExtractContents(chunkAtCell.GetCellValueFast(num7 + num8));
                        if (num9 == 0 || !(BlocksManager.Blocks[num9] is WoodBlock))
                        {
                            num8++;
                            continue;
                        }
                        goto IL_00e8;
                    }
                }
                continue;
IL_00e8:
                flag = true;
                break;
            }
            if (!flag)
            {
                base.SubsystemTerrain.ChangeCell(p.X, p.Y, p.Z, 0);
            }
        }