Refine ship orders and viewer controls

This commit is contained in:
2026-04-09 12:42:52 -04:00
parent 6c92ab50c8
commit 8503855a4c
64 changed files with 2939 additions and 2037 deletions

View File

@@ -314,24 +314,28 @@ public sealed class SpatialBuilder
ResourceNodeDefinition definition,
float oreAmount)
{
var depositCount = Math.Clamp((int)MathF.Round(MathF.Sqrt(MathF.Max(oreAmount, 1f)) / 18f), 4, 12);
var derivedDepositCount = Math.Clamp((int)MathF.Round(MathF.Sqrt(MathF.Max(oreAmount, 1f)) / 18f), 4, 18);
var depositCount = Math.Clamp(definition.ShardCount > 0 ? definition.ShardCount : derivedDepositCount, 4, 48);
var deposits = new List<ResourceDepositRuntime>(depositCount);
var weightTotal = 0f;
var weights = new float[depositCount];
var random = new Random(ComputeDeterministicSeed(systemId, nodeId, "resource-deposits"));
for (var index = 0; index < depositCount; index += 1)
{
var weight = 0.8f + (Hash01(systemId, nodeId, $"weight-{index}") * 1.6f);
var weight = 0.8f + (NextFloat01(random) * 1.6f);
weights[index] = weight;
weightTotal += weight;
}
var scatterRadius = MathF.Max(140f, LocalSpaceRadius * 0.58f);
// Resource node localspace should read as a compact mineable field around the node core,
// not as sparse debris spread across the entire anchor volume.
var scatterRadius = MathF.Max(120f, MathF.Min(LocalSpaceRadius * 0.2f, 900f));
for (var index = 0; index < depositCount; index += 1)
{
var angle = Hash01(systemId, nodeId, $"angle-{index}") * MathF.PI * 2f;
var radiusFactor = 0.22f + (Hash01(systemId, nodeId, $"radius-{index}") * 0.74f);
var angle = NextFloat01(random) * MathF.PI * 2f;
var radiusFactor = 0.12f + (NextFloat01(random) * 0.82f);
var radius = scatterRadius * MathF.Sqrt(radiusFactor);
var vertical = (Hash01(systemId, nodeId, $"vertical-{index}") - 0.5f) * MathF.Max(60f, scatterRadius * 0.14f);
var vertical = (NextFloat01(random) - 0.5f) * MathF.Max(40f, scatterRadius * 0.18f);
var localPosition = new Vector3(
MathF.Cos(angle) * radius,
vertical,
@@ -351,6 +355,32 @@ public sealed class SpatialBuilder
return deposits;
}
private static int ComputeDeterministicSeed(string systemId, string nodeId, string salt)
{
unchecked
{
var hash = 17;
foreach (var character in systemId)
{
hash = (hash * 31) + character;
}
foreach (var character in nodeId)
{
hash = (hash * 31) + character;
}
foreach (var character in salt)
{
hash = (hash * 31) + character;
}
return hash;
}
}
private static float NextFloat01(Random random) => (float)random.NextDouble();
private static float Hash01(string systemId, string nodeId, string salt)
{
unchecked
@@ -391,13 +421,15 @@ public sealed class SpatialBuilder
internal static ShipSpatialStateRuntime CreateInitialShipSpatialState(string systemId, Vector3 position, IReadOnlyCollection<AnchorRuntime> anchors)
{
var systemPosition = SimulationUnits.MetersToKilometers(position);
var nearestAnchor = anchors
.Where(anchor => anchor.SystemId == systemId)
.OrderBy(anchor => anchor.Position.DistanceTo(position))
.OrderBy(anchor => anchor.Position.DistanceTo(systemPosition))
.FirstOrDefault();
var localPosition = nearestAnchor is null
? position
: position.Subtract(nearestAnchor.Position);
var localPosition = position;
var resolvedSystemPosition = nearestAnchor is null
? systemPosition
: Add(nearestAnchor.Position, SimulationUnits.MetersToKilometers(localPosition));
return new ShipSpatialStateRuntime
{
@@ -405,7 +437,7 @@ public sealed class SpatialBuilder
SpaceLayer = SpaceLayerKind.LocalSpace,
CurrentAnchorId = nearestAnchor?.Id,
LocalPosition = localPosition,
SystemPosition = position,
SystemPosition = resolvedSystemPosition,
MovementRegime = MovementRegimeKind.LocalFlight,
};
}