179 lines
5.2 KiB
C#
179 lines
5.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Sandbox;
|
|
|
|
partial class Dedugan
|
|
{
|
|
[Property] public List<string> WorkshopItems { get; set; }
|
|
[Property] public ClothingContainer CurrentClothing { get; set; }
|
|
public static IReadOnlyList<Dedugan> All => InternalPlayers;
|
|
public static List<Dedugan> InternalPlayers = new List<Dedugan>();
|
|
public List<ClothingContainer.ClothingEntry> Clothings { get; set; }
|
|
public static Dedugan Local { get; set; }
|
|
|
|
private Guid _guid;
|
|
public static Dedugan FindLocalPlayer() => Local;
|
|
|
|
[Sync( SyncFlags.FromHost )]
|
|
public Guid ConnectionID
|
|
{
|
|
get => _guid;
|
|
set
|
|
{
|
|
_guid = value;
|
|
Connection = Connection.Find( _guid );
|
|
|
|
if ( _guid == Connection.Local.Id )
|
|
{
|
|
Local = this;
|
|
// ILocalPlayerEvent.Post( x => x.OnInitialized() );
|
|
}
|
|
|
|
InternalPlayers.RemoveAll( x => !x.IsValid() );
|
|
if ( !InternalPlayers.Contains( this ) )
|
|
InternalPlayers.Add( this );
|
|
}
|
|
}
|
|
|
|
public Connection Connection { get; private set; }
|
|
|
|
public ulong SteamID => Connection.SteamId;
|
|
public string Name => Connection.DisplayName;
|
|
|
|
public void SetupConnection( Connection connection )
|
|
{
|
|
ConnectionID = connection.Id;
|
|
GameObject.Name = $"{Name} / {SteamID}";
|
|
}
|
|
|
|
public static Dedugan GetByID( Guid id )
|
|
=> InternalPlayers.FirstOrDefault( x => x.ConnectionID == id );
|
|
|
|
public void OnNetworkSpawn( Connection owner )
|
|
{
|
|
CurrentClothing = ClothingContainer.CreateFromJson( owner.GetUserData( "avatar" ) );
|
|
|
|
var allowedCategories = new[]
|
|
{
|
|
Clothing.ClothingCategory.Skin, Clothing.ClothingCategory.Facial, Clothing.ClothingCategory.Eyes,
|
|
Clothing.ClothingCategory.Eyebrows, Clothing.ClothingCategory.Eyelashes,
|
|
Clothing.ClothingCategory.MakeupLips, Clothing.ClothingCategory.MakeupEyeshadow,
|
|
Clothing.ClothingCategory.MakeupEyeliner, Clothing.ClothingCategory.MakeupHighlighter,
|
|
Clothing.ClothingCategory.MakeupBlush, Clothing.ClothingCategory.MakeupSpecial,
|
|
Clothing.ClothingCategory.ComplexionFreckles, Clothing.ClothingCategory.ComplexionScars,
|
|
Clothing.ClothingCategory.ComplexionAcne, Clothing.ClothingCategory.FacialHairMustache,
|
|
Clothing.ClothingCategory.FacialHairBeard, Clothing.ClothingCategory.FacialHairStubble,
|
|
Clothing.ClothingCategory.FacialHairSideburns, Clothing.ClothingCategory.FacialHairGoatee,
|
|
Clothing.ClothingCategory.PierceNose, Clothing.ClothingCategory.PierceEyebrow,
|
|
Clothing.ClothingCategory.PierceSpecial, Clothing.ClothingCategory.Hair,
|
|
Clothing.ClothingCategory.HairShort, Clothing.ClothingCategory.HairMedium,
|
|
Clothing.ClothingCategory.HairLong, Clothing.ClothingCategory.HairUpdo,
|
|
Clothing.ClothingCategory.HairSpecial,
|
|
};
|
|
|
|
CurrentClothing.Clothing.RemoveAll( entry => !allowedCategories.Contains( entry.Clothing.Category ) );
|
|
CurrentClothing.Apply( Renderer );
|
|
}
|
|
|
|
CancellationTokenSource _cts;
|
|
|
|
// [Rpc.Broadcast]
|
|
// public void WearWorkshop( List<string> workshopItems )
|
|
// {
|
|
// _cts = new CancellationTokenSource();
|
|
// var token = _cts.Token;
|
|
//
|
|
// if ( workshopItems != null && workshopItems.Count > 0 )
|
|
// {
|
|
// Task.WhenAll( workshopItems.Select( x => InstallWorkshopClothing( x, token ) ) )
|
|
// .ContinueWith( ( tasks ) =>
|
|
// {
|
|
// foreach ( var cloth in tasks.Result )
|
|
// {
|
|
// if ( cloth is null )
|
|
// continue;
|
|
// Log.Info( cloth.Title );
|
|
// CurrentClothing.Add( cloth );
|
|
// }
|
|
// } );
|
|
// }
|
|
//
|
|
// CurrentClothing.Normalize();
|
|
// CurrentClothing.Apply( Renderer );
|
|
// Renderer.PostAnimationUpdate();
|
|
// }
|
|
|
|
[Rpc.Broadcast]
|
|
public void WearWorkshop( List<string> workshopItems )
|
|
{
|
|
AsyncWearWorkshop( workshopItems );
|
|
}
|
|
|
|
public async void AsyncWearWorkshop( List<string> workshopItems )
|
|
{
|
|
_cts = new CancellationTokenSource();
|
|
var token = _cts.Token;
|
|
|
|
if ( workshopItems != null && workshopItems.Count > 0 )
|
|
{
|
|
var tasks = workshopItems.Select( x => InstallWorkshopClothing( x, token ) );
|
|
|
|
foreach ( var task in tasks )
|
|
{
|
|
var c = await task;
|
|
|
|
if ( c is null )
|
|
continue;
|
|
|
|
CurrentClothing.Add( c );
|
|
}
|
|
}
|
|
|
|
CurrentClothing.Normalize();
|
|
CurrentClothing.Apply( Renderer );
|
|
Renderer.PostAnimationUpdate();
|
|
}
|
|
|
|
[Rpc.Broadcast]
|
|
public void StripByName( string name )
|
|
{
|
|
CurrentClothing.Clothing.RemoveAll( entry => entry.Clothing.Title == name );
|
|
|
|
CurrentClothing.Normalize();
|
|
CurrentClothing.Apply( Renderer );
|
|
Renderer.PostAnimationUpdate();
|
|
}
|
|
|
|
|
|
public void CancelDressing()
|
|
{
|
|
_cts?.Cancel();
|
|
_cts?.Dispose();
|
|
_cts = default;
|
|
}
|
|
|
|
|
|
async Task<Clothing> InstallWorkshopClothing( string ident, CancellationToken ct )
|
|
{
|
|
if ( string.IsNullOrEmpty( ident ) ) return default;
|
|
|
|
var package = await Package.FetchAsync( ident, false );
|
|
if ( package is null ) return default;
|
|
if ( package.TypeName != "clothing" ) return default;
|
|
if ( ct.IsCancellationRequested ) return default;
|
|
|
|
var primaryAsset = package.GetMeta<string>( "PrimaryAsset" );
|
|
if ( string.IsNullOrWhiteSpace( primaryAsset ) ) return default;
|
|
|
|
var fs = await package.MountAsync();
|
|
if ( fs is null ) return default;
|
|
if ( ct.IsCancellationRequested ) return default;
|
|
|
|
// try to load it
|
|
return ResourceLibrary.Get<Clothing>( primaryAsset );
|
|
}
|
|
}
|