84 lines
3.2 KiB
C#
84 lines
3.2 KiB
C#
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);
|
|
}
|
|
}
|