using Sand.Core; namespace Sand.ChunkPrototype; public sealed partial class PrototypeSparseSandAdapter { private void ApplyHeatEmission(int x, int y, float amount) { AdjustTemperatureAt(x, y, amount * 0.08f); AdjustTemperatureAt(x - 1, y, amount * 0.02f); AdjustTemperatureAt(x + 1, y, amount * 0.02f); AdjustTemperatureAt(x, y - 1, amount * 0.02f); AdjustTemperatureAt(x, y + 1, amount * 0.02f); } private void ApplyTemperatureDiffusion(int x, int y, PrototypeParticle particle) { if (!TryGetCellPage(x, y, out _, out var page, out var localX, out var localY)) { return; } var localTemperature = page.GetTemperature(localX, localY); var airDelta = localTemperature - _ambientTemperature; if (MathF.Abs(airDelta) > 0.5f) { var minTransfer = Math.Min(airDelta * -0.5f, airDelta * 0.5f); var maxTransfer = Math.Max(airDelta * -0.5f, airDelta * 0.5f); var transfer = Math.Clamp( airDelta * 0.05f * particle.AmbientCoolingMultiplier / MathF.Max(0.1f, particle.Conductivity <= 0f ? 1f : particle.Conductivity), minTransfer, maxTransfer); page.SetTemperature(localX, localY, localTemperature - transfer); localTemperature -= transfer; } DiffuseBetween(x, y, x + 1, y, particle, localTemperature); DiffuseBetween(x, y, x, y + 1, particle, localTemperature); } private void AdjustTemperatureAt(int x, int y, float delta) { if (!TryGetCellPage(x, y, out _, out var page, out var localX, out var localY)) { return; } page.SetTemperature(localX, localY, page.GetTemperature(localX, localY) + delta); } private void DiffuseBetween(int x, int y, int nx, int ny, PrototypeParticle particle, float localTemperature) { if (!TryGetCellPage(x, y, out _, out var sourcePage, out var sourceLocalX, out var sourceLocalY) || !TryGetCellPage(nx, ny, out _, out var targetPage, out var targetLocalX, out var targetLocalY)) { return; } var neighborParticle = targetPage[targetLocalX, targetLocalY]; if (neighborParticle.TypeId == 0) { return; } var neighborTemperature = targetPage.GetTemperature(targetLocalX, targetLocalY); var delta = localTemperature - neighborTemperature; if (MathF.Abs(delta) <= 0.5f) { return; } var sourceConductivity = MathF.Max(particle.Conductivity, 0.1f); var targetConductivity = MathF.Max(neighborParticle.Conductivity, 0.1f); var minTransfer = Math.Min(delta * -0.5f, delta * 0.5f); var maxTransfer = Math.Max(delta * -0.5f, delta * 0.5f); var transfer = Math.Clamp( delta * ((sourceConductivity + targetConductivity) * 0.5f) * 0.1f * particle.NeighborHeatTransferMultiplier, minTransfer, maxTransfer); sourcePage.SetTemperature(sourceLocalX, sourceLocalY, localTemperature - transfer); targetPage.SetTemperature(targetLocalX, targetLocalY, neighborTemperature + transfer); } }