Park/Buildings/Building.Persistence.cs
using HC3.Persistence;
using System.Text.Json.Nodes;
namespace HC3;
partial class Building : IPrefabSourceComponent<Building.SaveData>
{
/// <summary>
/// Hack so we don't forget which prefab this came from when it spawns.
/// </summary>
public string PrefabSource { get; private set; }
public sealed record SaveData( Vector3 Position, float Rotation, TintChannelData RedColor,
TintChannelData GreenColor,
TintChannelData BlueColor,
TintChannelData AlphaColor, JsonObject Metadata = null );
protected virtual JsonObject GetPersistentMetadata()
{
var obj = new JsonObject();
obj["Title"] = Title;
obj["Uses"] = Uses;
return obj;
}
protected virtual void SetPersistentMetadata( JsonObject obj )
{
if ( obj == null )
return;
if ( obj.TryGetPropertyValue( "Title", out var title ) )
{
Title = title.GetValue<string>();
}
if ( obj.TryGetPropertyValue( "Uses", out var uses ) )
{
Uses = uses.GetValue<int>();
}
}
SaveData IPrefabSourceComponent<SaveData>.GetSaveData() =>
new( GridManager.Instance.Terrain.WorldToGrid( WorldPosition ), WorldRotation.Yaw(), RedColor: RedChannel,
GreenColor: GreenChannel,
BlueColor: BlueChannel,
AlphaColor: AlphaChannel, GetPersistentMetadata() );
void IPrefabSourceComponent<SaveData>.Spawn( SaveData saveData )
{
WorldPosition = GridManager.Instance.Terrain.GridToWorld( saveData.Position );
WorldRotation = Rotation.FromYaw( saveData.Rotation );
IsPlaced = true;
Tags.Add( "building" );
Tags.Add( "selectable" );
// Load Metadata
SetPersistentMetadata( saveData.Metadata );
RedChannel = saveData.RedColor;
GreenChannel = saveData.GreenColor;
BlueChannel = saveData.BlueColor;
AlphaChannel = saveData.AlphaColor;
// Apply to tint component if it exists
var tint = GetTintComponent();
if ( tint.IsValid() )
{
tint.PrimaryColor = RedChannel.Color;
tint.SecondaryColor = GreenChannel.Color;
tint.AccentColor = BlueChannel.Color;
tint.DetailColor = AlphaChannel.Color;
}
GameObject.Root.NetworkSpawn();
}
protected override void OnAwake()
{
if ( GameObject.IsPrefabInstanceRoot )
{
PrefabSource = GameObject.PrefabInstanceSource;
}
}
}
file sealed class BuildingsSaveData : SpawnedPrefabSaveData<Building, Building.SaveData>
{
public override string PropertyName => "Buildings";
}