mirror of
https://github.com/Facepunch/sbox-public.git
synced 2026-01-02 19:38:24 -05:00
This commit imports the C# engine code and game files, excluding C++ source code. [Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
155 lines
4.1 KiB
C#
155 lines
4.1 KiB
C#
using Editor.MapDoc;
|
|
using NativeHammer;
|
|
|
|
namespace Editor.MapEditor;
|
|
|
|
/// <summary>
|
|
/// Create prop_static entities from a Package model.
|
|
/// </summary>
|
|
[CanDrop( "model" )]
|
|
[Expose]
|
|
class ModelDropTarget : IMapViewDropTarget
|
|
{
|
|
MapEntity Entity { get; set; }
|
|
|
|
public void DragEnter( Package package, MapView view )
|
|
{
|
|
// Get this early before any async shit ( only really needed cause of free drag mode )
|
|
Vector3 normal = Vector3.Zero;
|
|
Vector3 position = Vector3.Zero;
|
|
view.native.GetDropTarget( ref normal, ref position, view.MousePosition );
|
|
|
|
Entity = CreateModelEntityFromPackage( view.native, package, position );
|
|
|
|
// Letting native hammer deal with this shit, it's not great though..
|
|
view.native.EnterFreeDragMode( view.MousePosition, Entity, Vector3.Up, true );
|
|
}
|
|
|
|
public void DragMove( MapView view )
|
|
{
|
|
if ( !Entity.IsValid() )
|
|
return;
|
|
|
|
//
|
|
// Free drag mode keeps a copy of the baseline entity that it restores from every drag
|
|
// So just fucking hack around it and restore it
|
|
// As we get more and more Hammer C# API exposed we can do our own free drag and ignore this shit
|
|
//
|
|
var model = Entity.GetKeyValue( "model" );
|
|
view.native.UpdateFreeDragMode( view.MousePosition, false );
|
|
Entity.SetKeyValue( "model", model );
|
|
|
|
}
|
|
|
|
public void DragDropped( MapView view )
|
|
{
|
|
view.native.ExitFreeDragMode( false );
|
|
|
|
History.MarkUndoPosition( "Dropped Model" );
|
|
History.KeepNew( Entity );
|
|
}
|
|
|
|
public void DragLeave( MapView view )
|
|
{
|
|
view.native.ExitFreeDragMode( true );
|
|
|
|
if ( Entity.IsValid() )
|
|
view.MapDoc.DeleteNode( Entity );
|
|
}
|
|
|
|
static MapEntity CreateModelEntityFromPackage( CMapView view, Package package, Vector3 position )
|
|
{
|
|
var entity = new MapEntity( view.GetMapDoc() );
|
|
entity.ClassName = "prop_static";
|
|
entity.Position = position;
|
|
|
|
//
|
|
// If we already have the package installed, no need to query any remote shit
|
|
// Set the model immediately and exit
|
|
//
|
|
var installedPackage = AssetSystem.CloudDirectory.FindPackage( package.FullIdent );
|
|
if ( installedPackage != null )
|
|
{
|
|
var modelName = installedPackage.PrimaryAsset;
|
|
if ( FileSystem.Cloud.FileExists( modelName ) )
|
|
{
|
|
entity.SetKeyValue( "model", modelName );
|
|
return entity;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Async install the model package, and then update the entity's model
|
|
// We're passing the entity node id for safety
|
|
//
|
|
SetEntityToPackageModelAsync( entity, package.FullIdent );
|
|
|
|
return entity;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Installs the package and sets the model on the entity when that's done
|
|
/// </summary>
|
|
static async void SetEntityToPackageModelAsync( MapEntity entity, string packageIdent )
|
|
{
|
|
ThreadSafe.AssertIsMainThread();
|
|
|
|
//
|
|
// Fetch full package for the meta
|
|
//
|
|
var package = await Package.Fetch( packageIdent, false );
|
|
|
|
//
|
|
// Set some default bounds so the user knows the right size whilst it loads
|
|
//
|
|
{
|
|
if ( !entity.IsValid() )
|
|
return;
|
|
|
|
var mins = package.GetMeta( "RenderMins", Vector3.Zero );
|
|
var maxs = package.GetMeta( "RenderMaxs", Vector3.Zero );
|
|
|
|
entity.SetDefaultBounds( mins, maxs );
|
|
}
|
|
|
|
//
|
|
// Install our package
|
|
//
|
|
var asset = await AssetSystem.InstallAsync( package, loading: ( float progress ) =>
|
|
{
|
|
if ( !entity.IsValid() ) return;
|
|
LoadingProgress[entity] = progress;
|
|
Hammer.DirtyViewHuds(); // ?
|
|
} );
|
|
|
|
if ( asset == null ) return;
|
|
|
|
//
|
|
// Package is installed, update the model and we're done.
|
|
//
|
|
{
|
|
if ( entity.IsValid() )
|
|
{
|
|
entity.SetKeyValue( "model", asset.Path );
|
|
}
|
|
}
|
|
|
|
LoadingProgress.Remove( entity );
|
|
}
|
|
|
|
static Dictionary<MapEntity, float> LoadingProgress = new();
|
|
|
|
[Event( "hammer.rendermapview" )]
|
|
protected static void RenderLoadProgress( MapView oniichan )
|
|
{
|
|
// You could do some lovely stuff here if you really wanted
|
|
// But just showing the % is plenty
|
|
foreach ( var kvp in LoadingProgress )
|
|
{
|
|
if ( !kvp.Key.IsValid() ) continue;
|
|
Gizmo.Draw.Sprite( kvp.Key.Position + Vector3.Up * 16, 16, "materials/gizmo/downloads.png" );
|
|
Gizmo.Draw.Text( $"Downloading {kvp.Value * 100}%", new Transform( kvp.Key.Position ), size: 14 * Application.DpiScale );
|
|
}
|
|
}
|
|
}
|