146 lines
7.3 KiB
C#
146 lines
7.3 KiB
C#
#nullable enable
|
|
|
|
using System.Collections.Generic;
|
|
using Demo2.Domain;
|
|
using Unity.Collections;
|
|
using Unity.Entities;
|
|
|
|
namespace Demo2.ECS
|
|
{
|
|
public static class Demo2SnapshotCodec
|
|
{
|
|
public static Demo2Snapshot Capture(EntityManager manager, Entity singleton, IReadOnlyList<string>? ruleIds = null)
|
|
{
|
|
var simulation = manager.GetComponentData<Demo2SimulationState>(singleton);
|
|
var economy = manager.GetComponentData<Demo2EconomyState>(singleton);
|
|
var core = manager.GetComponentData<Demo2CoreHealth>(singleton);
|
|
var stats = manager.GetComponentData<Demo2CycleStats>(singleton);
|
|
var snapshot = new Demo2Snapshot
|
|
{
|
|
Tick = simulation.Tick,
|
|
Seed = simulation.Seed,
|
|
Phase = simulation.Phase,
|
|
Cycle = simulation.Cycle,
|
|
CoreHealth = core.Value,
|
|
Money = economy.Money,
|
|
Payload = economy.Payload,
|
|
MultiplierMilli = economy.MultiplierMilli,
|
|
Energy = economy.Energy,
|
|
ExcessFirepower = economy.ExcessFirepower,
|
|
RuleAppliedCycle = simulation.RuleAppliedCycle,
|
|
SpeedMultiplier = simulation.SpeedMultiplier,
|
|
Extracted = stats.Extracted,
|
|
Transported = stats.Transported,
|
|
Processed = stats.Processed,
|
|
AmmoProduced = stats.AmmoProduced,
|
|
CompletedSameRecipeStreak = stats.CompletedSameRecipeStreak,
|
|
LastRecipeId = stats.LastRecipeId,
|
|
Faults = stats.Faults,
|
|
BeltOccupancy = stats.BeltOccupancy,
|
|
BeltCapacity = stats.BeltCapacity,
|
|
IronFuelAdjacent = stats.IronFuelAdjacent,
|
|
FirstBatch = stats.FirstBatch,
|
|
DuplicateNextOutputs = stats.DuplicateNextOutputs,
|
|
StateHash = simulation.StateHash,
|
|
RuleIds = ruleIds == null ? new List<string>() : new List<string>(ruleIds)
|
|
};
|
|
|
|
using var entities = manager.GetAllEntities(Allocator.Temp);
|
|
for (var i = 0; i < entities.Length; i++)
|
|
{
|
|
var entity = entities[i];
|
|
if (!manager.HasComponent<Demo2StableId>(entity) || !manager.HasComponent<Demo2GridPosition>(entity)) continue;
|
|
var row = new Demo2SnapshotEntity { StableId = manager.GetComponentData<Demo2StableId>(entity).Value };
|
|
var position = manager.GetComponentData<Demo2GridPosition>(entity);
|
|
row.X = position.X;
|
|
row.Y = position.Y;
|
|
if (manager.HasComponent<Demo2MachineState>(entity))
|
|
{
|
|
var machine = manager.GetComponentData<Demo2MachineState>(entity);
|
|
row.MachineKind = machine.Kind;
|
|
row.Rotation = machine.Rotation;
|
|
row.RecipeId = machine.RecipeId;
|
|
row.Progress = machine.ProgressTicks;
|
|
row.Quantity = machine.StoredInput;
|
|
row.Faults = machine.Faults;
|
|
row.PendingOutputs = machine.PendingOutputs;
|
|
if (manager.HasComponent<Demo2TurretAmmo>(entity)) row.TurretAmmo = manager.GetComponentData<Demo2TurretAmmo>(entity).Value;
|
|
}
|
|
else if (manager.HasComponent<Demo2MaterialState>(entity))
|
|
{
|
|
var material = manager.GetComponentData<Demo2MaterialState>(entity);
|
|
row.MaterialKind = material.Kind;
|
|
row.Rotation = material.Direction;
|
|
row.Progress = material.SubCellProgress;
|
|
row.Quantity = material.Quantity;
|
|
row.MachineKind = (Demo2MachineKind)255;
|
|
}
|
|
snapshot.Entities.Add(row);
|
|
}
|
|
snapshot.Entities.Sort((left, right) => left.StableId.CompareTo(right.StableId));
|
|
return snapshot;
|
|
}
|
|
|
|
public static void Restore(EntityManager manager, Entity singleton, Demo2Snapshot snapshot)
|
|
{
|
|
using (var all = manager.GetAllEntities(Allocator.Temp))
|
|
for (var i = 0; i < all.Length; i++) if (all[i] != singleton) manager.DestroyEntity(all[i]);
|
|
|
|
var simulation = manager.GetComponentData<Demo2SimulationState>(singleton);
|
|
simulation.Tick = snapshot.Tick;
|
|
simulation.Seed = snapshot.Seed;
|
|
simulation.Phase = snapshot.Phase;
|
|
simulation.Cycle = snapshot.Cycle;
|
|
simulation.StateHash = snapshot.StateHash;
|
|
simulation.RuleAppliedCycle = snapshot.RuleAppliedCycle;
|
|
simulation.SpeedMultiplier = snapshot.SpeedMultiplier;
|
|
simulation.NextStableId = 0;
|
|
manager.SetComponentData(singleton, simulation);
|
|
manager.SetComponentData(singleton, new Demo2CoreHealth { Value = snapshot.CoreHealth });
|
|
manager.SetComponentData(singleton, new Demo2EconomyState
|
|
{
|
|
Money = snapshot.Money, Payload = snapshot.Payload, MultiplierMilli = snapshot.MultiplierMilli,
|
|
Energy = snapshot.Energy,
|
|
ExcessFirepower = snapshot.ExcessFirepower
|
|
});
|
|
manager.SetComponentData(singleton, new Demo2CycleStats
|
|
{
|
|
Extracted = snapshot.Extracted,
|
|
Transported = snapshot.Transported,
|
|
Processed = snapshot.Processed,
|
|
AmmoProduced = snapshot.AmmoProduced,
|
|
CompletedSameRecipeStreak = snapshot.CompletedSameRecipeStreak,
|
|
LastRecipeId = snapshot.LastRecipeId,
|
|
Faults = snapshot.Faults,
|
|
BeltOccupancy = snapshot.BeltOccupancy,
|
|
BeltCapacity = snapshot.BeltCapacity,
|
|
IronFuelAdjacent = snapshot.IronFuelAdjacent,
|
|
FirstBatch = snapshot.FirstBatch,
|
|
DuplicateNextOutputs = snapshot.DuplicateNextOutputs
|
|
});
|
|
|
|
foreach (var row in snapshot.Entities)
|
|
{
|
|
if ((byte)row.MachineKind == 255)
|
|
Demo2EcsFactory.CreateMaterial(manager, row.StableId, row.MaterialKind, row.X, row.Y, row.Rotation, row.Quantity);
|
|
else
|
|
{
|
|
var entity = Demo2EcsFactory.CreateMachine(manager, row.StableId, row.MachineKind, row.X, row.Y, row.Rotation, row.RecipeId);
|
|
var machine = manager.GetComponentData<Demo2MachineState>(entity);
|
|
machine.ProgressTicks = row.Progress;
|
|
machine.StoredInput = row.Quantity;
|
|
machine.Faults = row.Faults;
|
|
machine.PendingOutputs = row.PendingOutputs;
|
|
manager.SetComponentData(entity, machine);
|
|
if (row.MachineKind == Demo2MachineKind.Turret && !manager.HasComponent<Demo2TurretAmmo>(entity))
|
|
manager.AddComponentData(entity, new Demo2TurretAmmo());
|
|
if (manager.HasComponent<Demo2TurretAmmo>(entity))
|
|
manager.SetComponentData(entity, new Demo2TurretAmmo { Value = row.TurretAmmo });
|
|
}
|
|
if (row.StableId > simulation.NextStableId) simulation.NextStableId = row.StableId;
|
|
}
|
|
manager.SetComponentData(singleton, simulation);
|
|
}
|
|
}
|
|
}
|