Complete universe model migration
This commit is contained in:
@@ -315,6 +315,8 @@ public sealed class WorldService
|
||||
string.Equals(candidate.FactionId, faction.Id, StringComparison.Ordinal)
|
||||
&& string.Equals(candidate.SystemId, system.Definition.Id, StringComparison.Ordinal));
|
||||
var defaultBehavior = CreateSpawnBehavior(request, definition, system.Definition.Id, homeStation);
|
||||
var spatialState = SpatialBuilder.CreateInitialShipSpatialState(system.Definition.Id, spawnPosition, _world.Anchors);
|
||||
var localPosition = spatialState.LocalPosition ?? Vector3.Zero;
|
||||
|
||||
var ship = new ShipRuntime
|
||||
{
|
||||
@@ -322,9 +324,9 @@ public sealed class WorldService
|
||||
SystemId = system.Definition.Id,
|
||||
Definition = definition,
|
||||
FactionId = faction.Id,
|
||||
Position = spawnPosition,
|
||||
TargetPosition = spawnPosition,
|
||||
SpatialState = SpatialBuilder.CreateInitialShipSpatialState(system.Definition.Id, spawnPosition, _world.Celestials),
|
||||
Position = localPosition,
|
||||
TargetPosition = localPosition,
|
||||
SpatialState = spatialState,
|
||||
DefaultBehavior = defaultBehavior,
|
||||
Skills = ShipBootstrapPolicy.CreateSkills(definition),
|
||||
Health = definition.Hull,
|
||||
@@ -352,15 +354,18 @@ public sealed class WorldService
|
||||
? $"{faction.Label} {ToTitleCaseToken(objective)} {CountFactionStationsInSystem(faction.Id, system.Definition.Id) + 1}"
|
||||
: request.Label.Trim();
|
||||
var stationId = $"station-{faction.Id}-{objective}-{Guid.NewGuid():N}".ToLowerInvariant();
|
||||
var position = ResolveStationSpawnPosition(system.Definition.Id);
|
||||
var requestedPosition = ResolveStationSpawnPosition(system.Definition.Id);
|
||||
var anchor = ResolveNearestConstructibleAnchor(system.Definition.Id, requestedPosition)
|
||||
?? throw new InvalidOperationException($"System '{system.Definition.Id}' does not have a valid constructible anchor for station spawning.");
|
||||
var station = new StationRuntime
|
||||
{
|
||||
Id = stationId,
|
||||
SystemId = system.Definition.Id,
|
||||
AnchorId = anchor.Id,
|
||||
Label = label,
|
||||
Color = faction.Color,
|
||||
Objective = objective,
|
||||
Position = position,
|
||||
Position = Vector3.Zero,
|
||||
FactionId = faction.Id,
|
||||
PolicySetId = faction.DefaultPolicySetId,
|
||||
Health = 600f,
|
||||
@@ -375,6 +380,7 @@ public sealed class WorldService
|
||||
station.PopulationCapacity = GetStationSupportedPopulation(_world.ModuleDefinitions, station);
|
||||
station.WorkforceRequired = GetStationRequiredWorkforce(_world.ModuleDefinitions, station);
|
||||
_world.Stations.Add(station);
|
||||
anchor.OccupyingStructureId = station.Id;
|
||||
|
||||
new GeopoliticalSimulationService().Update(_world, 0f, []);
|
||||
PublishSnapshotRefreshUnsafe("spawn-station", $"Spawned station {station.Id}", "station", station.Id);
|
||||
@@ -490,6 +496,7 @@ public sealed class WorldService
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
null);
|
||||
|
||||
_history.Enqueue(worldDelta);
|
||||
@@ -526,6 +533,7 @@ public sealed class WorldService
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
null);
|
||||
|
||||
_history.Enqueue(worldDelta);
|
||||
@@ -608,6 +616,8 @@ public sealed class WorldService
|
||||
var shipId = $"ship-{playerFaction.Id}-{definition.Id}-{Guid.NewGuid():N}".ToLowerInvariant();
|
||||
var spawnPosition = ResolveSpawnPosition(system.Definition.Id);
|
||||
var defaultBehavior = CreateSpawnBehavior(request, definition, system.Definition.Id, null);
|
||||
var spatialState = SpatialBuilder.CreateInitialShipSpatialState(system.Definition.Id, spawnPosition, _world.Anchors);
|
||||
var localPosition = spatialState.LocalPosition ?? Vector3.Zero;
|
||||
|
||||
var ship = new ShipRuntime
|
||||
{
|
||||
@@ -615,9 +625,9 @@ public sealed class WorldService
|
||||
SystemId = system.Definition.Id,
|
||||
Definition = definition,
|
||||
FactionId = playerFaction.Id,
|
||||
Position = spawnPosition,
|
||||
TargetPosition = spawnPosition,
|
||||
SpatialState = SpatialBuilder.CreateInitialShipSpatialState(system.Definition.Id, spawnPosition, _world.Celestials),
|
||||
Position = localPosition,
|
||||
TargetPosition = localPosition,
|
||||
SpatialState = spatialState,
|
||||
DefaultBehavior = defaultBehavior,
|
||||
Skills = ShipBootstrapPolicy.CreateSkills(definition),
|
||||
Health = definition.Hull,
|
||||
@@ -712,7 +722,7 @@ public sealed class WorldService
|
||||
SourceStationId = request.SourceStationId,
|
||||
DestinationStationId = request.DestinationStationId,
|
||||
ItemId = request.ItemId,
|
||||
NodeId = request.NodeId,
|
||||
AnchorId = request.AnchorId,
|
||||
ConstructionSiteId = request.ConstructionSiteId,
|
||||
ModuleId = request.ModuleId,
|
||||
WaitSeconds = MathF.Max(0f, request.WaitSeconds ?? 0f),
|
||||
@@ -780,7 +790,7 @@ public sealed class WorldService
|
||||
ship.DefaultBehavior.AreaSystemId = request.AreaSystemId;
|
||||
ship.DefaultBehavior.TargetEntityId = request.TargetEntityId;
|
||||
ship.DefaultBehavior.ItemId = request.ItemId;
|
||||
ship.DefaultBehavior.PreferredNodeId = request.PreferredNodeId;
|
||||
ship.DefaultBehavior.PreferredAnchorId = request.PreferredAnchorId;
|
||||
ship.DefaultBehavior.PreferredConstructionSiteId = request.PreferredConstructionSiteId;
|
||||
ship.DefaultBehavior.PreferredModuleId = request.PreferredModuleId;
|
||||
ship.DefaultBehavior.TargetPosition = request.TargetPosition is null
|
||||
@@ -807,7 +817,7 @@ public sealed class WorldService
|
||||
SourceStationId = template.SourceStationId,
|
||||
DestinationStationId = template.DestinationStationId,
|
||||
ItemId = template.ItemId,
|
||||
NodeId = template.NodeId,
|
||||
AnchorId = template.AnchorId,
|
||||
ConstructionSiteId = template.ConstructionSiteId,
|
||||
ModuleId = template.ModuleId,
|
||||
WaitSeconds = template.WaitSeconds ?? 0f,
|
||||
@@ -905,6 +915,16 @@ public sealed class WorldService
|
||||
return new Vector3(MathF.Cos(angle) * radius, 0f, MathF.Sin(angle) * radius);
|
||||
}
|
||||
|
||||
private AnchorRuntime? ResolveNearestConstructibleAnchor(string systemId, Vector3 position) =>
|
||||
_world.Anchors
|
||||
.Where(candidate => string.Equals(candidate.SystemId, systemId, StringComparison.Ordinal))
|
||||
.Where(candidate => SpatialBuilder.IsConstructibleAnchorKind(candidate.Kind))
|
||||
.OrderBy(candidate => candidate.Position.DistanceTo(position))
|
||||
.FirstOrDefault();
|
||||
|
||||
private string? ResolveNearestAnchorId(string systemId, Vector3 position) =>
|
||||
ResolveNearestConstructibleAnchor(systemId, position)?.Id;
|
||||
|
||||
private IReadOnlyList<string> BuildStarterStationModules(string factionId, string objective)
|
||||
{
|
||||
var modules = new List<string>();
|
||||
@@ -1079,9 +1099,9 @@ public sealed class WorldService
|
||||
}
|
||||
|
||||
var systemFilter = scope.SystemId;
|
||||
if (string.Equals(scope.ScopeKind, "local-celestial", StringComparison.OrdinalIgnoreCase) && systemFilter is null && scope.CelestialId is not null)
|
||||
if (string.Equals(scope.ScopeKind, "local-anchor", StringComparison.OrdinalIgnoreCase) && systemFilter is null && scope.AnchorId is not null)
|
||||
{
|
||||
systemFilter = ResolveCelestialSystemId(scope.CelestialId);
|
||||
systemFilter = ResolveAnchorSystemId(scope.AnchorId);
|
||||
}
|
||||
|
||||
return delta with
|
||||
@@ -1091,6 +1111,7 @@ public sealed class WorldService
|
||||
.Where((evt) => IsEventVisibleToScope(evt, scope, systemFilter))
|
||||
.ToList(),
|
||||
Celestials = delta.Celestials.Where((celestial) => systemFilter is null || celestial.SystemId == systemFilter).ToList(),
|
||||
Anchors = delta.Anchors.Where((anchor) => systemFilter is null || anchor.SystemId == systemFilter).ToList(),
|
||||
Nodes = delta.Nodes.Where((node) => systemFilter is null || node.SystemId == systemFilter).ToList(),
|
||||
Stations = delta.Stations.Where((station) => systemFilter is null || station.SystemId == systemFilter).ToList(),
|
||||
Claims = delta.Claims.Where((claim) => systemFilter is null || claim.SystemId == systemFilter).ToList(),
|
||||
@@ -1136,8 +1157,8 @@ public sealed class WorldService
|
||||
ScopeEntityId = scopeEntityId,
|
||||
};
|
||||
|
||||
private string? ResolveCelestialSystemId(string celestialId) =>
|
||||
_world.Celestials.FirstOrDefault((c) => c.Id == celestialId)?.SystemId;
|
||||
private string? ResolveAnchorSystemId(string anchorId) =>
|
||||
_world.Anchors.FirstOrDefault((anchor) => anchor.Id == anchorId)?.SystemId;
|
||||
|
||||
private string? ResolveMarketOrderSystemId(string orderId)
|
||||
{
|
||||
@@ -1181,7 +1202,7 @@ public sealed class WorldService
|
||||
{
|
||||
"universe" => true,
|
||||
"system" => evt.ScopeKind == "universe" || evt.ScopeEntityId == systemFilter,
|
||||
"local-celestial" => evt.ScopeKind == "universe" || evt.ScopeEntityId == systemFilter,
|
||||
"local-anchor" => evt.ScopeKind == "universe" || evt.ScopeEntityId == systemFilter,
|
||||
_ => true,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user