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--; } } } }
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)); }
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); }
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); }
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++; } } } }
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); } }
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); } } } }
public void UpdateIsTop(int value, int x, int y, int z) { Terrain terrain = base.SubsystemTerrain.Terrain; if (y < 255) { TerrainChunk chunkAtCell = terrain.GetChunkAtCell(x, z); if (chunkAtCell != null) { int num = TerrainChunk.CalculateCellIndex(x & 0xF, y, z & 0xF); int contents = Terrain.ExtractContents(chunkAtCell.GetCellValueFast(num + 1)); int data = Terrain.ExtractData(value); bool isTop = !m_fluidBlock.IsTheSameFluid(contents); chunkAtCell.SetCellValueFast(num, Terrain.ReplaceData(value, FluidBlock.SetIsTop(data, isTop))); } } }
public static void PaintSelective(this TerrainChunk chunk, Cell[] cells, int x, int y, int z, int src = BasaltBlock.Index) { x -= chunk.Origin.X; z -= chunk.Origin.Y; for (int i = 0; i < cells.Length; i++) { Cell cell = cells[i]; int y2 = cell.Y + y; if (y2 >= 0 && y2 < 128) { int index = TerrainChunk.CalculateCellIndex(cell.X + x & 15, y2, cell.Z + z & 15); if (src == chunk.GetCellValueFast(index)) { chunk.SetCellValueFast(index, cell.Value); } } } }
public static void PaintFastSelective(this TerrainChunk chunk, Cell[] cells, int x, int y, int z, int onlyInBlock = BasaltBlock.Index) { x -= chunk.Origin.X; z -= chunk.Origin.Y; for (int i = 0; i < cells.Length; i++) { Cell cell = cells[i]; int y2 = cell.Y + y; if (y2 >= 0 && y2 < 128) { int index = TerrainChunk.CalculateCellIndex(cell.X + x & 15, y2, cell.Z + z & 15); if (Terrain.ExtractContents(onlyInBlock) == Terrain.ExtractContents(chunk.GetCellValueFast(index))) { //SubsystemMineral.StoreItemData(cell.Value); chunk.SetCellValueFast(index, onlyInBlock); } } } }
public static void Fade(TerrainChunk chunk, int?color = null) { if (!chunk.IsLoaded) { return; } for (int i = 16; i-- > 0;) { for (int j = 16; i-- > 0;) { int n = TerrainChunk.CalculateCellIndex(i, 0, j); for (int k = 128; k-- > 0;) { if (BlocksManager.Blocks[Terrain.ExtractContents(chunk.GetCellValueFast(n + k))] is IPaintableBlock block) { chunk.SetCellValueFast(n, block.Paint(SubsystemTerrain, 0, color)); } } } } }
public void PaintFastSelective(TerrainChunk chunk, int x, int y, int z, int onlyInValue) { 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 < 256 && num3 >= 0 && num3 < 16) { int index = TerrainChunk.CalculateCellIndex(num, num2, num3); int cellValueFast = chunk.GetCellValueFast(index); if (onlyInValue == cellValueFast) { chunk.SetCellValueFast(index, cell.Value); } } } }
public override void OnChunkInitialized(TerrainChunk chunk) { if (!(Utils.SubsystemTerrain.TerrainContentsGenerator is TerrainContentsGenerator generator) || chunk.IsLoaded) { return; } int x = chunk.Coords.X - 1; int y = chunk.Coords.Y - 1; const int f1 = 0x63721054, f2 = 0x04317562, f3 = 0x52473601, f4 = 0x61234057, f5 = 0x07142563, f6 = 0x53721604, f7 = 0x64317052, f8 = 0x02473561, f9 = 0x51234607, fa = 0x67142053, fb = 0x03721564, fc = 0x54317602, fd = 0x62473051, fe = 0x01234567, ff = 0x57142603; Random random; for (int i = x; i < x + 2; i++) { int k, ix16 = i << 4; for (int j = y; j < y + 2; j++) { random = new Random(generator.m_seed + i + (f1 ^ f4 ^ f5 ^ f7 ^ fa ^ fc ^ fd) * j); int jx16 = j << 4; float num2 = generator.CalculateMountainRangeFactor(ix16, jx16); const int index = BasaltBlock.Index, index2 = BasaltBlock.Index; for (k = 1 + (int)(2f * num2 * SimplexNoise.OctavedNoise(i ^ fe, j ^ ff, 0.33f, 1, 1f, 1f)); k-- != 0;) { chunk.PaintFastSelective(SmallBrushes[random.Int() & 15].Cells, ix16 | (random.Int() & 15), random.UniformInt(2, 30), jx16 | (random.Int() & 15), index2 | (int)BrushType.Au << 15); } for (k = 1 + (int)(2f * num2 * SimplexNoise.OctavedNoise(i + 713, j + f3, 0.33f, 1, 1f, 1f)); k-- != 0;) { chunk.PaintFastSelective(SmallBrushes[random.Int() & 15].Cells, ix16 | (random.Int() & 15), random.UniformInt(2, 30), jx16 | (random.Int() & 15), index2 | (int)BrushType.Ag << 15); } for (k = 1 + (int)(2f * num2 * SimplexNoise.OctavedNoise(i + f2, j + 396, 0.33f, 1, 1f, 1f)); k-- != 0;) { chunk.PaintFastSelective(PtBrushes[random.Int() & 15].Cells, ix16 | (random.Int() & 15), random.UniformInt(2, 15), jx16 | (random.Int() & 15), index2 | (int)BrushType.Pt << 15); } for (k = 3 + (int)(2f * num2 * SimplexNoise.OctavedNoise(i + f6, j + 131, 0.33f, 1, 1f, 1f)); k-- != 0;) { chunk.PaintFastSelective(ABrushes[random.Int() & 15].Cells, ix16 | (random.Int() & 15), random.UniformInt(2, 50), jx16 | (random.Int() & 15), index | (int)BrushType.Pb << 15); } for (k = (int)(0.5f + 2f * num2 * SimplexNoise.OctavedNoise(i + 432, j + f9, 0.33f, 1, 1f, 1f)); k-- != 0;) { chunk.PaintFastSelective(BBrushes[random.Int() & 15].Cells, ix16 | (random.Int() & 15), random.UniformInt(2, 15), jx16 | (random.Int() & 15), index | (int)BrushType.Hg << 15); } for (k = 3 + (int)(2f * num2 * SimplexNoise.OctavedNoise(i + 711, j + fb, 0.33f, 1, 1f, 1f)); k-- != 0;) { chunk.PaintFastSelective(BBrushes[random.Int() & 15].Cells, ix16 | (random.Int() & 15), random.UniformInt(2, 40), jx16 | (random.Int() & 15), index | (int)BrushType.Sn << 15); } for (k = 2 + (int)(2f * num2 * SimplexNoise.OctavedNoise(i + f8, j + 272, 0.33f, 1, 1f, 1f)); k-- != 0;) { chunk.PaintFastSelective(ABrushes[random.Int() & 15].Cells, ix16 | (random.Int() & 15), random.UniformInt(2, 50), jx16 | (random.Int() & 15), index | (int)BrushType.Ti << 15); } for (k = 2 + (int)(2f * num2 * SimplexNoise.OctavedNoise(i + fa, j + fc, 0.33f, 1, 1f, 1f)); k-- != 0;) { chunk.PaintFastSelective(BBrushes[random.Int() & 15].Cells, ix16 | (random.Int() & 15), random.UniformInt(2, 50), jx16 | (random.Int() & 15), index | (int)BrushType.Cr << 15); } for (k = 2 + (int)(2f * num2 * SimplexNoise.OctavedNoise(i + f3, j + f6, 0.33f, 1, 1f, 1f)); k-- != 0;) { chunk.PaintFastSelective(ABrushes[random.Int() & 15].Cells, ix16 | (random.Int() & 15), random.UniformInt(2, 50), jx16 | (random.Int() & 15), index | (int)BrushType.Ni << 15); } for (k = 20 + (int)(8f * num2 * SimplexNoise.OctavedNoise(i + fa ^ f5 + f1, j + fc - f9, 0.33f, 1, 1f, 1f)); k-- != 0;) { chunk.PaintMaskSelective(ABrushes[random.Int() & 15].Cells, ix16 | (random.Int() & 15), random.UniformInt(2, 50), jx16 | (random.Int() & 15), index | 65536 << 14); } for (k = 9 + (int)(8f * num2 * SimplexNoise.OctavedNoise(i + f5 ^ f8 + f1, j + f9 - fc, 0.33f, 1, 1f, 1f)); k-- != 0;) { chunk.PaintMaskSelective(ABrushes[random.Int() & 15].Cells, ix16 | (random.Int() & 15), random.UniformInt(2, 50), jx16 | (random.Int() & 15), index | 32768 << 14); } for (k = 1 + (int)(2f * num2 * SimplexNoise.OctavedNoise(i + fc, j + f9, 0.33f, 1, 1f, 1f)); k-- != 0;) { chunk.PaintFastSelective(SmallBrushes[random.Int() & 15].Cells, ix16 | (random.Int() & 15), random.UniformInt(2, 20), jx16 | (random.Int() & 15), index2 | (int)BrushType.U << 15); } for (k = 3 + (int)(2f * num2 * SimplexNoise.OctavedNoise(i + f3, j + f1, 0.33f, 1, 1f, 1f)); k-- != 0;) { chunk.PaintFastSelective(ABrushes[random.Int() & 15].Cells, ix16 | (random.Int() & 15), random.UniformInt(45, 70), jx16 | (random.Int() & 15), 3 | (int)BrushType.P << 15); } if (generator.CalculateOceanShoreDistance(ix16, y << 4) < -90f) { int n = TerrainChunk.CalculateCellIndex(random.Int() & 15, 35, random.Int() & 15); for (k = 0; k < 45; k++) { if (Terrain.ExtractContents(chunk.GetCellValueFast(n + k)) == WaterBlock.Index && BlocksManager.Blocks[Terrain.ExtractContents(chunk.GetCellValueFast(n + k - 1))].IsCollidable) { chunk.SetCellValueFast(n + k, IceBlock.Index | 32 << 14); break; } } } } random = new Random(generator.m_seed ^ (x << 16 | y)); if ((random.Int() & 1) != 0) { chunk.PaintSelective(OilPocketCells[random.Int() & 15], x << 16 | (random.Int() & 15), random.UniformInt(40, 70), y << 16 | (random.Int() & 15), 3); } } }
public void Update(float dt) { Terrain terrain = m_subsystemTerrain.Terrain; m_pollCount += (float)(terrain.AllocatedChunks.Length * 16 * 16) * dt / 60f; m_pollCount = MathUtils.Clamp(m_pollCount, 0f, 200f); TerrainChunk nextChunk = terrain.GetNextChunk(m_pollChunkCoordinates.X, m_pollChunkCoordinates.Y); if (nextChunk == null) { return; } while (m_pollCount >= 1f) { if (nextChunk.State <= TerrainChunkState.InvalidContents4) { m_pollCount -= 65536f; } else { while (m_pollX < 16) { while (m_pollZ < 16) { if (m_pollCount < 1f) { return; } m_pollCount -= 1f; int topHeightFast = nextChunk.GetTopHeightFast(m_pollX, m_pollZ); int num = TerrainChunk.CalculateCellIndex(m_pollX, 0, m_pollZ); int num2 = 0; while (num2 <= topHeightFast) { int cellValueFast = nextChunk.GetCellValueFast(num); int num3 = Terrain.ExtractContents(cellValueFast); if (num3 != 0) { SubsystemPollableBlockBehavior[] array = m_pollableBehaviorsByContents[num3]; for (int i = 0; i < array.Length; i++) { array[i].OnPoll(cellValueFast, nextChunk.Origin.X + m_pollX, num2, nextChunk.Origin.Y + m_pollZ, m_pollPass); } } num2++; num++; } m_pollZ++; } m_pollZ = 0; m_pollX++; } m_pollX = 0; } this.ScanningChunkCompleted?.Invoke(nextChunk); nextChunk = terrain.GetNextChunk(nextChunk.Coords.X + 1, nextChunk.Coords.Y); if (nextChunk == null) { break; } if (Terrain.ComparePoints(nextChunk.Coords, m_pollChunkCoordinates) < 0) { m_pollPass++; } m_pollChunkCoordinates = nextChunk.Coords; } }
public unsafe bool LoadChunkBlocks(TerrainChunk chunk) { bool result = false; int num = chunk.Origin.X >> 4; int num2 = chunk.Origin.Y >> 4; try { if (!m_chunkOffsets.TryGetValue(new Point2(num, num2), out long value)) { return(result); } _ = Time.RealTime; m_stream.Seek(value, SeekOrigin.Begin); ReadChunkHeader(m_stream); m_stream.Read(m_buffer, 0, 262144); try { fixed(byte *ptr = &m_buffer[0]) { int *ptr2 = (int *)ptr; for (int i = 0; i < 16; i++) { for (int j = 0; j < 16; j++) { int num3 = TerrainChunk.CalculateCellIndex(i, 0, j); int num4 = 0; while (num4 < 256) { chunk.SetCellValueFast(num3, *ptr2); num4++; num3++; ptr2++; } } } } } finally { } m_stream.Read(m_buffer, 0, 1024); try { fixed(byte *ptr = &m_buffer[0]) { int *ptr3 = (int *)ptr; for (int k = 0; k < 16; k++) { for (int l = 0; l < 16; l++) { m_terrain.SetShaftValue(k + chunk.Origin.X, l + chunk.Origin.Y, *ptr3); ptr3++; } } } } finally { } result = true; _ = Time.RealTime; return(result); } catch (Exception e) { Log.Error(ExceptionManager.MakeFullErrorMessage($"Error loading data for chunk ({num},{num2}).", e)); return(result); } }
public unsafe void SaveChunkBlocks(TerrainChunk chunk) { _ = Time.RealTime; int num = chunk.Origin.X >> 4; int num2 = chunk.Origin.Y >> 4; try { bool flag = false; if (m_chunkOffsets.TryGetValue(new Point2(num, num2), out long value)) { m_stream.Seek(value, SeekOrigin.Begin); } else { flag = true; value = m_stream.Length; m_stream.Seek(value, SeekOrigin.Begin); } WriteChunkHeader(m_stream, num, num2); try { fixed(byte *ptr = &m_buffer[0]) { int *ptr2 = (int *)ptr; for (int i = 0; i < 16; i++) { for (int j = 0; j < 16; j++) { int num3 = TerrainChunk.CalculateCellIndex(i, 0, j); int num4 = 0; while (num4 < 256) { *ptr2 = chunk.GetCellValueFast(num3); num4++; num3++; ptr2++; } } } } } finally { } m_stream.Write(m_buffer, 0, 262144); try { fixed(byte *ptr = &m_buffer[0]) { int *ptr3 = (int *)ptr; for (int k = 0; k < 16; k++) { for (int l = 0; l < 16; l++) { *ptr3 = m_terrain.GetShaftValue(k + chunk.Origin.X, l + chunk.Origin.Y); ptr3++; } } } } finally { } m_stream.Write(m_buffer, 0, 1024); if (flag) { m_stream.Flush(); int num5 = m_chunkOffsets.Count % 65536 * 3 * 4; m_stream.Seek(num5, SeekOrigin.Begin); WriteInt(m_stream, num); WriteInt(m_stream, num2); WriteInt(m_stream, m_chunkOffsets.Count); m_chunkOffsets[new Point2(num, num2)] = value; } m_stream.Flush(); } catch (Exception e) { Log.Error(ExceptionManager.MakeFullErrorMessage($"Error writing data for chunk ({num},{num2}).", e)); } _ = Time.RealTime; }
public void SaveChunkBlocks(TerrainChunk chunk) { _ = Time.RealTime; Terrain terrain = m_subsystemTerrain.Terrain; int num = chunk.Origin.X >> 4; int num2 = chunk.Origin.Y >> 4; try { bool flag = false; if (m_chunkOffsets.TryGetValue(new Point2(num, num2), out int value)) { m_stream.Seek(value, SeekOrigin.Begin); } else { flag = true; value = (int)m_stream.Length; m_stream.Seek(value, SeekOrigin.Begin); } WriteChunkHeader(m_stream, num, num2); int num3 = 0; 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 cellValueFast = chunk.GetCellValueFast(num4++); m_buffer[num3++] = (byte)cellValueFast; m_buffer[num3++] = (byte)(cellValueFast >> 8); } } } m_stream.Write(m_buffer, 0, 131072); num3 = 0; for (int l = 0; l < 16; l++) { for (int m = 0; m < 16; m++) { int shaftValue = terrain.GetShaftValue(l + chunk.Origin.X, m + chunk.Origin.Y); m_buffer[num3++] = (byte)shaftValue; m_buffer[num3++] = (byte)(shaftValue >> 8); m_buffer[num3++] = (byte)(shaftValue >> 16); m_buffer[num3++] = (byte)(shaftValue >> 24); } } m_stream.Write(m_buffer, 0, 1024); if (flag) { m_stream.Flush(); int num5 = m_chunkOffsets.Count % 65536 * 3 * 4; m_stream.Seek(num5, SeekOrigin.Begin); WriteInt(m_stream, num); WriteInt(m_stream, num2); WriteInt(m_stream, value); m_chunkOffsets[new Point2(num, num2)] = value; } } catch (Exception e) { Log.Error(ExceptionManager.MakeFullErrorMessage($"Error writing data for chunk ({num},{num2}).", e)); } _ = Time.RealTime; }