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 static float?CalculateSmoothLight(SubsystemTerrain subsystemTerrain, Vector3 p) { p -= new Vector3(0.5f); int num = (int)MathUtils.Floor(p.X); int num2 = (int)MathUtils.Floor(p.Y); int num3 = (int)MathUtils.Floor(p.Z); int x = (int)MathUtils.Ceiling(p.X); int num4 = (int)MathUtils.Ceiling(p.Y); int z = (int)MathUtils.Ceiling(p.Z); Terrain terrain = subsystemTerrain.Terrain; if (num2 >= 0 && num4 <= 255) { TerrainChunk chunkAtCell = terrain.GetChunkAtCell(num, num3); TerrainChunk chunkAtCell2 = terrain.GetChunkAtCell(x, num3); TerrainChunk chunkAtCell3 = terrain.GetChunkAtCell(num, z); TerrainChunk chunkAtCell4 = terrain.GetChunkAtCell(x, z); if (chunkAtCell != null && chunkAtCell.State >= TerrainChunkState.InvalidVertices1 && chunkAtCell2 != null && chunkAtCell2.State >= TerrainChunkState.InvalidVertices1 && chunkAtCell3 != null && chunkAtCell3.State >= TerrainChunkState.InvalidVertices1 && chunkAtCell4 != null && chunkAtCell4.State >= TerrainChunkState.InvalidVertices1) { float f = p.X - (float)num; float f2 = p.Y - (float)num2; float f3 = p.Z - (float)num3; float x2 = terrain.GetCellLightFast(num, num2, num3); float x3 = terrain.GetCellLightFast(num, num2, z); float x4 = terrain.GetCellLightFast(num, num4, num3); float x5 = terrain.GetCellLightFast(num, num4, z); float x6 = terrain.GetCellLightFast(x, num2, num3); float x7 = terrain.GetCellLightFast(x, num2, z); float x8 = terrain.GetCellLightFast(x, num4, num3); float x9 = terrain.GetCellLightFast(x, num4, z); float x10 = MathUtils.Lerp(x2, x6, f); float x11 = MathUtils.Lerp(x3, x7, f); float x12 = MathUtils.Lerp(x4, x8, f); float x13 = MathUtils.Lerp(x5, x9, f); float x14 = MathUtils.Lerp(x10, x12, f2); float x15 = MathUtils.Lerp(x11, x13, f2); float num5 = MathUtils.Lerp(x14, x15, f3); int num6 = (int)MathUtils.Floor(num5); int num7 = (int)MathUtils.Ceiling(num5); float f4 = num5 - (float)num6; return(MathUtils.Lerp(LightIntensityByLightValue[num6], LightIntensityByLightValue[num7], f4)); } } return(null); }
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); } } }
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 bool IsPowered(Terrain terrain, int x, int y, int z) { var chunk = terrain.GetChunkAtCell(x, z); if (y < 0 || y > 127 || chunk == null) { return(false); } int cellValue = terrain.GetCellValueFast(x + 1, y, z); if (FurnaceNBlock.GetHeatLevel(cellValue) != 0) { cellValue = Terrain.ExtractContents(cellValue); if (cellValue == EngineBlock.Index || cellValue == EngineHBlock.Index) { return(true); } } cellValue = terrain.GetCellValueFast(x - 1, y, z); if (FurnaceNBlock.GetHeatLevel(cellValue) != 0) { cellValue = Terrain.ExtractContents(cellValue); if (cellValue == EngineBlock.Index || cellValue == EngineHBlock.Index) { return(true); } } if (y < 127) { cellValue = chunk.GetCellValueFast(x & 15, y + 1, z & 15); if (FurnaceNBlock.GetHeatLevel(cellValue) != 0) { cellValue = Terrain.ExtractContents(cellValue); if (cellValue == EngineBlock.Index || cellValue == EngineHBlock.Index) { return(true); } } } if (y > 0) { cellValue = chunk.GetCellValueFast(x & 15, y - 1, z & 15); if (FurnaceNBlock.GetHeatLevel(cellValue) != 0) { cellValue = Terrain.ExtractContents(cellValue); if (cellValue == EngineBlock.Index || cellValue == EngineHBlock.Index) { return(true); } } } cellValue = terrain.GetCellValueFast(x, y, z + 1); if (FurnaceNBlock.GetHeatLevel(cellValue) != 0) { cellValue = Terrain.ExtractContents(cellValue); if (cellValue == EngineBlock.Index || cellValue == EngineHBlock.Index) { return(true); } } cellValue = terrain.GetCellValueFast(x, y, z - 1); if (FurnaceNBlock.GetHeatLevel(cellValue) != 0) { cellValue = Terrain.ExtractContents(cellValue); if (cellValue == EngineBlock.Index || cellValue == EngineHBlock.Index) { return(true); } } return(false); }
public void CalculateTemperature(int x, int y, int z, float meterTemperature, float meterInsulation, out float temperature, out float temperatureFlux) { m_toVisit.Clear(); for (int i = 0; i < m_visited.Length; i++) { m_visited[i] = 0; } float num = 0f; float num2 = 0f; float num3 = 0f; float num4 = 0f; float num5 = 0f; float num6 = 0f; m_toVisit.Add(133152); for (int j = 0; j < m_toVisit.Count; j++) { int num7 = m_toVisit.Array[j]; if ((m_visited[num7 / 32] & (1 << num7)) != 0) { continue; } m_visited[num7 / 32] |= 1 << num7; int num8 = (num7 & 0x3F) - 32; int num9 = ((num7 >> 6) & 0x3F) - 32; int num10 = ((num7 >> 12) & 0x3F) - 32; int num11 = num8 + x; int num12 = num9 + y; int num13 = num10 + z; Terrain terrain = base.SubsystemTerrain.Terrain; TerrainChunk chunkAtCell = terrain.GetChunkAtCell(num11, num13); if (chunkAtCell == null || num12 < 0 || num12 >= 256) { continue; } int x2 = num11 & 0xF; int y2 = num12; int z2 = num13 & 0xF; int cellValueFast = chunkAtCell.GetCellValueFast(x2, y2, z2); int num14 = Terrain.ExtractContents(cellValueFast); Block block = BlocksManager.Blocks[num14]; float heat = GetHeat(cellValueFast); if (heat > 0f) { int num15 = MathUtils.Abs(num8) + MathUtils.Abs(num9) + MathUtils.Abs(num10); int num16 = (num15 <= 0) ? 1 : (4 * num15 * num15 + 2); float num17 = 1f / (float)num16; num5 += num17 * 36f * heat; num6 += num17; } else if (block.IsHeatBlocker(cellValueFast)) { int num18 = MathUtils.Abs(num8) + MathUtils.Abs(num9) + MathUtils.Abs(num10); int num19 = (num18 <= 0) ? 1 : (4 * num18 * num18 + 2); float num20 = 1f / (float)num19; float num21 = terrain.SeasonTemperature; float num22 = SubsystemWeather.GetTemperatureAdjustmentAtHeight(y2); float num23 = (block is WaterBlock) ? (MathUtils.Max((float)chunkAtCell.GetTemperatureFast(x2, z2) + num21 - 6f, 0f) + num22) : ((!(block is IceBlock)) ? ((float)chunkAtCell.GetTemperatureFast(x2, z2) + num21 + num22) : (0f + num21 + num22)); num += num20 * num23; num2 += num20; } else if (y >= chunkAtCell.GetTopHeightFast(x2, z2)) { int num24 = MathUtils.Abs(num8) + MathUtils.Abs(num9) + MathUtils.Abs(num10); int num25 = (num24 <= 0) ? 1 : (4 * num24 * num24 + 2); float num26 = 1f / (float)num25; PrecipitationShaftInfo precipitationShaftInfo = m_subsystemWeather.GetPrecipitationShaftInfo(x, z); float num27 = terrain.SeasonTemperature; float num28 = (y >= precipitationShaftInfo.YLimit) ? MathUtils.Lerp(0f, -2f, precipitationShaftInfo.Intensity) : 0f; float num29 = MathUtils.Lerp(-6f, 0f, m_subsystemSky.SkyLightIntensity); float num30 = SubsystemWeather.GetTemperatureAdjustmentAtHeight(y2); num3 += num26 * ((float)chunkAtCell.GetTemperatureFast(x2, z2) + num27 + num28 + num29 + num30); num4 += num26; } else if (m_toVisit.Count < 4090) { if (num8 > -30) { m_toVisit.Add(num7 - 1); } if (num8 < 30) { m_toVisit.Add(num7 + 1); } if (num9 > -30) { m_toVisit.Add(num7 - 64); } if (num9 < 30) { m_toVisit.Add(num7 + 64); } if (num10 > -30) { m_toVisit.Add(num7 - 4096); } if (num10 < 30) { m_toVisit.Add(num7 + 4096); } } } float num31 = 0f; for (int k = -7; k <= 7; k++) { for (int l = -7; l <= 7; l++) { TerrainChunk chunkAtCell2 = base.SubsystemTerrain.Terrain.GetChunkAtCell(x + k, z + l); if (chunkAtCell2 == null || chunkAtCell2.State < TerrainChunkState.InvalidVertices1) { continue; } for (int m = -7; m <= 7; m++) { int num32 = k * k + m * m + l * l; if (num32 > 49 || num32 <= 0) { continue; } int x3 = (x + k) & 0xF; int num33 = y + m; int z3 = (z + l) & 0xF; if (num33 >= 0 && num33 < 256) { float heat2 = GetHeat(chunkAtCell2.GetCellValueFast(x3, num33, z3)); if (heat2 > 0f && !base.SubsystemTerrain.Raycast(new Vector3(x, y, z) + new Vector3(0.5f, 0.75f, 0.5f), new Vector3(x + k, y + m, z + l) + new Vector3(0.5f, 0.75f, 0.5f), useInteractionBoxes: false, skipAirBlocks: true, delegate(int raycastValue, float d) { Block block2 = BlocksManager.Blocks[Terrain.ExtractContents(raycastValue)]; return(block2.IsCollidable && !block2.IsTransparent); }).HasValue) { num31 += heat2 * 3f / (float)(num32 + 2); } } } } } float num34 = 0f; float num35 = 0f; if (num31 > 0f) { float num36 = 3f * num31; num34 += 35f * num36; num35 += num36; } if (num2 > 0f) { float num37 = 1f; num34 += num / num2 * num37; num35 += num37; } if (num4 > 0f) { float num38 = 4f * MathUtils.Pow(num4, 0.25f); num34 += num3 / num4 * num38; num35 += num38; } if (num6 > 0f) { float num39 = 1.5f * MathUtils.Pow(num6, 0.25f); num34 += num5 / num6 * num39; num35 += num39; } if (meterInsulation > 0f) { num34 += meterTemperature * meterInsulation; num35 += meterInsulation; } temperature = ((num35 > 0f) ? (num34 / num35) : meterTemperature); temperatureFlux = num35 - meterInsulation; }