Helper/ClothingModelSuffixStripper.cs
namespace Skateboard;
public sealed class ClothingModelSuffixStripper : Component
{
[Property] public Dresser Dresser { get; set; }
private bool _applied;
protected override void OnStart()
{
Dresser ??= Components.Get<Dresser>();
}
protected override void OnUpdate()
{
if ( Dresser is null )
return;
if ( Dresser.IsDressing )
{
_applied = false;
return;
}
if ( _applied )
return;
OverrideClothingModels();
}
private void OverrideClothingModels()
{
var target = Dresser.BodyTarget;
if ( target is null || !target.IsValid() )
return;
var clothingEntries = GetClothingEntries();
if ( clothingEntries is null || clothingEntries.Count == 0 )
{
_applied = true;
return;
}
var foundClothingObject = false;
foreach ( var entry in clothingEntries )
{
var clothing = entry?.Clothing;
if ( clothing is null )
continue;
var modelPath = clothing.Model;
if ( string.IsNullOrWhiteSpace( modelPath ) )
continue;
var clothingObject = FindClothingObject( target.GameObject, clothing.ResourceName );
if ( clothingObject is null )
continue;
foundClothingObject = true;
var renderer = clothingObject.Components.Get<SkinnedModelRenderer>();
if ( renderer is null )
continue;
var model = Model.Load( modelPath );
if ( model is null || !model.IsValid() || model.IsError )
continue;
if ( renderer.Model == model )
continue;
renderer.Model = model;
}
if ( foundClothingObject )
_applied = true;
}
private List<ClothingContainer.ClothingEntry> GetClothingEntries()
{
switch ( Dresser.Source )
{
case Dresser.ClothingSource.Manual:
return Dresser.Clothing;
case Dresser.ClothingSource.OwnerConnection:
return GetOwnerClothingEntries();
case Dresser.ClothingSource.LocalUser:
return ClothingContainer.CreateFromLocalUser()?.Clothing;
}
return null;
}
private List<ClothingContainer.ClothingEntry> GetOwnerClothingEntries()
{
var owner = Dresser.Network?.Owner;
if ( owner is null )
return null;
var clothingData = owner.GetUserData( "avatar" );
if ( string.IsNullOrEmpty( clothingData ) )
return null;
var container = new ClothingContainer();
container.Deserialize( clothingData );
container.Normalize();
return container.Clothing;
}
private static GameObject FindClothingObject( GameObject root, string resourceName )
{
if ( root is null || string.IsNullOrWhiteSpace( resourceName ) )
return null;
var name = $"Clothing - {resourceName}";
foreach ( var child in root.Children )
{
if ( child.Name == name )
return child;
}
foreach ( var child in root.GetAllObjects( false ) )
{
if ( child.Name == name )
return child;
}
return null;
}
}