A GameObjectSystem that periodically scans skinned model renderers in the scene and injects an ExpresionesNextbot component into game objects tagged as sbh_nextbot that have bodygroups and do not already have the component. It skips accessory objects tagged sbh_accesorio.
namespace SBH;
using Sandbox;
/// <summary>
/// [SBHBase] Inyecta ExpresionesNextbot (con defaults) a todo nextbot cuyo
/// modelo tenga bodygroups y no traiga ya el componente — mismo patrón de
/// escaneo que RitmoInyector. Cubre la fusión de carteles: un bot spawneado
/// como personaje sin bodygroups que se transforma en uno que sí tiene,
/// gana sus expresiones al próximo escaneo. Si el prefab ya trae el
/// componente (el addon lo emite con índices calibrados), se respeta.
/// </summary>
public sealed class ExpresionesInyector : GameObjectSystem
{
TimeSince _desdeEscaneo;
public ExpresionesInyector( Scene scene ) : base( scene )
{
Listen( Stage.StartUpdate, 25, Escanear, "ExpresionesInyector" );
}
void Escanear()
{
if ( _desdeEscaneo < 1f ) return;
_desdeEscaneo = 0f;
foreach ( var renderer in Scene.GetAllComponents<SkinnedModelRenderer>() )
{
var go = renderer.GameObject;
if ( !go.IsValid() || !go.Tags.Has( "sbh_nextbot" ) ) continue;
// Accesorios bonemerge: heredan el tag del bot vestido pero son
// decoración — la cara la maneja el dueño, no el accesorio
if ( go.Tags.Has( "sbh_accesorio" ) ) continue;
if ( !renderer.HasBodyGroups ) continue;
if ( go.Components.Get<ExpresionesNextbot>( true ) != null ) continue;
go.Components.Create<ExpresionesNextbot>();
Log.Info( $"🙂 ExpresionesNextbot inyectado a {go.Name} (bodygroups detectados)" );
}
}
}