mirror of
https://github.com/Facepunch/sbox-public.git
synced 2026-01-02 11:28:19 -05:00
This commit imports the C# engine code and game files, excluding C++ source code. [Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
124 lines
4.8 KiB
C#
124 lines
4.8 KiB
C#
using System.Text.Json;
|
|
using System.Text.Json.Nodes;
|
|
|
|
namespace Sandbox;
|
|
|
|
public partial class GameObject
|
|
{
|
|
/// <summary>
|
|
/// Converts Legacy Prefab Instance Data and variables to a patch.
|
|
/// - Root level properties: Transform, Flags, Network... are converted to property overrides
|
|
/// - Prefab Variables are converted to component property overrides
|
|
/// - Prefab to instance guid lookup is created
|
|
/// </summary>
|
|
[Expose, JsonUpgrader( typeof( GameObject ), 1 )]
|
|
internal static void Upgrader_v1( JsonObject obj )
|
|
{
|
|
if ( obj[JsonKeys.PrefabInstanceSource] is JsonValue __Prefab && __Prefab.TryGetValue( out string prefabSource ) )
|
|
{
|
|
if ( !obj.ContainsKey( JsonKeys.PrefabInstancePatch ) )
|
|
{
|
|
var prefabFile = ResourceLibrary.Get<PrefabFile>( prefabSource );
|
|
|
|
if ( !prefabFile.IsValid() )
|
|
{
|
|
var name = obj.TryGetPropertyValue( JsonKeys.Name, out var nameNode ) ? nameNode.Deserialize<string>() : null;
|
|
|
|
Log.Warning( $"GameObject {name ?? "unknown"} Upgrader failed to upgrade prefab instance, prefab '{prefabSource}' couldn't be loaded and is likely missing." );
|
|
return;
|
|
}
|
|
|
|
// Convert the existing isntance data into a patch
|
|
var instancePatch = ConvertLegacyPrefabInstanceToPatch( obj, prefabFile );
|
|
var instanceGuid = obj[JsonKeys.Id].Deserialize<Guid>();
|
|
|
|
var prefabScene = (PrefabCacheScene)SceneUtility.GetPrefabScene( prefabFile );
|
|
|
|
// We wont have a lookup table stored yet so create a new one
|
|
var prefabLookup = SceneUtility.CreateUniqueGuidLookup( prefabScene.FullPrefabInstanceJson, instanceGuid );
|
|
|
|
// It's easier to clear the object and start from scratch
|
|
obj.Clear();
|
|
|
|
obj[JsonKeys.PrefabInstanceSource] = JsonValue.Create( prefabSource );
|
|
obj[JsonKeys.Id] = instanceGuid;
|
|
obj[JsonKeys.PrefabInstancePatch] = Json.ToNode( instancePatch );
|
|
obj[JsonKeys.PrefabIdToInstanceId] = Json.ToNode( prefabLookup );
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Backwards combatibility for old prefab instances.
|
|
/// </summary>
|
|
private static Json.Patch ConvertLegacyPrefabInstanceToPatch( JsonObject legacyData, PrefabFile prefabFile )
|
|
{
|
|
var instancePatch = new Json.Patch();
|
|
|
|
var prefabScene = SceneUtility.GetPrefabScene( prefabFile );
|
|
|
|
var variables = legacyData[JsonKeys.PrefabInstanceVariables] as JsonObject;
|
|
|
|
if ( variables is not null )
|
|
{
|
|
foreach ( (string name, JsonNode value) in variables )
|
|
{
|
|
#pragma warning disable CS0612
|
|
var variable = prefabScene.Variables.Where( x => x.Id == name ).FirstOrDefault();
|
|
#pragma warning restore CS0612
|
|
if ( variable is null )
|
|
{
|
|
Log.Warning( $"Prefab Variable not in prefab: {name}" );
|
|
continue;
|
|
}
|
|
|
|
foreach ( var target in variable.Targets )
|
|
{
|
|
instancePatch.PropertyOverrides.Add( new Json.PropertyOverride
|
|
{
|
|
Target = new Json.ObjectIdentifier
|
|
{
|
|
Type = "Component", // we only ever support components!
|
|
IdValue = target.Id.ToString()
|
|
},
|
|
Property = target.Property,
|
|
Value = value
|
|
} );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void TryAddOverrideTargetingPrefab( JsonObject legacyData, string propertyName, JsonNode defaultValue = null )
|
|
{
|
|
if ( !legacyData.TryGetPropertyValue( propertyName, out var propertyNode ) && defaultValue is null ) return;
|
|
|
|
instancePatch.PropertyOverrides.Add( new Json.PropertyOverride
|
|
{
|
|
Target = new Json.ObjectIdentifier
|
|
{
|
|
Type = "GameObject",
|
|
IdValue = prefabScene.Id.ToString()
|
|
},
|
|
Property = propertyName,
|
|
Value = propertyNode ?? defaultValue
|
|
} );
|
|
}
|
|
|
|
TryAddOverrideTargetingPrefab( legacyData, JsonKeys.Position, Json.ToNode( Vector3.Zero ) );
|
|
TryAddOverrideTargetingPrefab( legacyData, JsonKeys.Rotation, Json.ToNode( Rotation.Identity ) );
|
|
TryAddOverrideTargetingPrefab( legacyData, JsonKeys.Scale, Json.ToNode( Vector3.One ) );
|
|
TryAddOverrideTargetingPrefab( legacyData, JsonKeys.Name );
|
|
TryAddOverrideTargetingPrefab( legacyData, JsonKeys.Enabled, false );
|
|
TryAddOverrideTargetingPrefab( legacyData, JsonKeys.Flags, 0 );
|
|
TryAddOverrideTargetingPrefab( legacyData, JsonKeys.Tags, prefabFile.RootObject[JsonKeys.Tags] ?? "" );
|
|
TryAddOverrideTargetingPrefab( legacyData, JsonKeys.NetworkMode, prefabFile.RootObject[JsonKeys.NetworkMode] ?? (int)NetworkMode.Snapshot );
|
|
TryAddOverrideTargetingPrefab( legacyData, JsonKeys.AlwaysTransmit, prefabFile.RootObject[JsonKeys.AlwaysTransmit] ?? true );
|
|
TryAddOverrideTargetingPrefab( legacyData, JsonKeys.NetworkOrphaned, prefabFile.RootObject[JsonKeys.NetworkOrphaned] ?? (int)NetworkOrphaned.Destroy );
|
|
TryAddOverrideTargetingPrefab( legacyData, JsonKeys.OwnerTransfer, prefabFile.RootObject[JsonKeys.OwnerTransfer] ?? (int)OwnerTransfer.Fixed );
|
|
TryAddOverrideTargetingPrefab( legacyData, JsonKeys.NetworkInterpolation, prefabFile.RootObject[JsonKeys.NetworkInterpolation] ?? false );
|
|
|
|
return instancePatch;
|
|
}
|
|
}
|