mirror of
https://github.com/Facepunch/sbox-public.git
synced 2026-01-13 16:59:38 -05:00
This commit imports the C# engine code and game files, excluding C++ source code. [Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
140 lines
3.9 KiB
C#
140 lines
3.9 KiB
C#
using NativeEngine;
|
|
|
|
namespace Sandbox;
|
|
|
|
public abstract class MapLoader
|
|
{
|
|
/// <summary>
|
|
/// Holds key values for the map object
|
|
/// </summary>
|
|
public readonly struct ObjectEntry
|
|
{
|
|
public string TypeName { get; init; }
|
|
public string TargetName { get; init; }
|
|
public string ParentName { get; init; }
|
|
public Vector3 Position { get; init; }
|
|
public Angles Angles { get; init; }
|
|
public Rotation Rotation { get; init; }
|
|
public Vector3 Scales { get; init; }
|
|
public Transform Transform { get; init; }
|
|
public Vector3 WorldOrigin { get; init; }
|
|
public ITagSet Tags { get; init; }
|
|
|
|
private readonly Dictionary<uint, string> values = new();
|
|
|
|
internal ObjectEntry( CEntityKeyValues keyValues, Vector3 origin )
|
|
{
|
|
var keyCount = keyValues.GetKeyCount();
|
|
for ( int i = 0; i < keyCount; i++ )
|
|
{
|
|
var key = keyValues.GetKey( i );
|
|
values.Add( key, keyValues.GetValueString( key, null ) );
|
|
}
|
|
|
|
TypeName = GetValueString( "classname", null );
|
|
TargetName = GetValueString( "targetname", null );
|
|
ParentName = GetValueString( "parentname", null );
|
|
WorldOrigin = origin;
|
|
Position = GetValue<Vector3>( "origin" ) + WorldOrigin;
|
|
Angles = GetValue<Angles>( "angles" );
|
|
Scales = GetValue( "scales", Vector3.One );
|
|
Rotation = Angles.ToRotation();
|
|
Transform = new( Position, Rotation, Scales );
|
|
|
|
var tags = GetValue<string>( "tags" ) ?? string.Empty;
|
|
Tags = new ReadOnlyTagSet( tags.Split( ",", StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries ) );
|
|
}
|
|
|
|
private string GetValueString( string key, string defaultValue )
|
|
{
|
|
if ( values.TryGetValue( StringToken.FindOrCreate( key ), out var value ) )
|
|
{
|
|
return value;
|
|
}
|
|
|
|
return defaultValue;
|
|
}
|
|
|
|
public readonly T GetValue<T>( string key, T defaultValue = default )
|
|
{
|
|
var value = GetValueString( key, null );
|
|
if ( string.IsNullOrWhiteSpace( value ) )
|
|
return defaultValue;
|
|
|
|
return (T)value.ToType( typeof( T ) );
|
|
}
|
|
|
|
public readonly T GetResource<T>( string key, T defaultValue = default ) where T : Resource
|
|
{
|
|
var value = GetValueString( key, null );
|
|
if ( string.IsNullOrWhiteSpace( value ) )
|
|
return defaultValue;
|
|
|
|
return Resource.Load( typeof( T ), value ) as T;
|
|
}
|
|
|
|
public readonly string GetString( string key, string defaultValue = default )
|
|
{
|
|
return GetValueString( key, defaultValue );
|
|
}
|
|
}
|
|
|
|
public SceneWorld World { get; private set; }
|
|
public PhysicsWorld PhysicsWorld { get; private set; }
|
|
public Vector3 WorldOrigin { get; private set; }
|
|
|
|
protected readonly List<SceneObject> SceneObjects = new();
|
|
|
|
public MapLoader( SceneWorld world, PhysicsWorld physics, Vector3 origin = default )
|
|
{
|
|
World = world;
|
|
PhysicsWorld = physics;
|
|
WorldOrigin = origin;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Create an object from a serialized object entry
|
|
/// </summary>
|
|
protected abstract void CreateObject( ObjectEntry kv );
|
|
|
|
internal void CreateEntities( IWorldReference worldRef, string entityLumpName )
|
|
{
|
|
var entityCount = worldRef.GetEntityCount( entityLumpName );
|
|
if ( entityCount == 0 )
|
|
return;
|
|
|
|
var entries = new List<ObjectEntry>( entityCount );
|
|
|
|
for ( int i = 0; i < entityCount; ++i )
|
|
{
|
|
var kv = worldRef.GetEntityKeyValues( entityLumpName, i );
|
|
if ( !kv.IsValid )
|
|
continue;
|
|
|
|
entries.Add( new ObjectEntry( kv, WorldOrigin ) );
|
|
}
|
|
|
|
entries.Sort( ( a, b ) =>
|
|
{
|
|
if ( string.IsNullOrEmpty( a.ParentName ) && string.IsNullOrEmpty( b.ParentName ) ) return 0;
|
|
if ( string.IsNullOrEmpty( a.ParentName ) ) return -1;
|
|
if ( string.IsNullOrEmpty( b.ParentName ) ) return 1;
|
|
if ( a.ParentName == b.TargetName ) return 1;
|
|
if ( b.ParentName == a.TargetName ) return -1;
|
|
return string.Compare( a.TargetName, b.TargetName, StringComparison.Ordinal );
|
|
} );
|
|
|
|
foreach ( var kv in entries )
|
|
{
|
|
try
|
|
{
|
|
CreateObject( kv );
|
|
}
|
|
catch ( System.Exception e )
|
|
{
|
|
Log.Warning( e, $"Error when trying to create entity ({kv.TypeName})" );
|
|
}
|
|
}
|
|
}
|
|
}
|