using Content.Shared.Clothing.Components; using Content.Shared.Inventory.Events; using Robust.Shared.Serialization.Manager; using Content.Shared.Tag; using Content.Shared._White.ClothingGrant.Components; using Robust.Shared.Prototypes; using Robust.Shared.Timing; namespace Content.Shared._White.ClothingGrant.Systems; public sealed class ClothingGrantingSystem : EntitySystem { [Dependency] private readonly IComponentFactory _componentFactory = default!; [Dependency] private readonly ISerializationManager _serializationManager = default!; [Dependency] private readonly IGameTiming _timing = default!; [Dependency] private readonly TagSystem _tagSystem = default!; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnCompEquip); SubscribeLocalEvent(OnCompUnequip); SubscribeLocalEvent(OnTagEquip); SubscribeLocalEvent(OnTagUnequip); } private void OnCompEquip(EntityUid uid, ClothingGrantComponentComponent component, GotEquippedEvent args) { if (_timing.ApplyingState) return; if (!TryComp(uid, out var clothing)) return; if (!clothing.Slots.HasFlag(args.SlotFlags)) return; if (component.Components.Count > 8) { Logger.Error("Although a component registry supports multiple components, we cannot bookkeep more than 8 component for ClothingGrantComponent at this time."); return; } AddComponents(args.Equipee, component.Components); component.IsActive = true; Dirty(uid, component); } public void AddComponents(EntityUid uid, ComponentRegistry components) { foreach (var (name, data) in components) { var newComp = (Component) _componentFactory.GetComponent(name); if (HasComp(uid, newComp.GetType())) continue; newComp.Owner = uid; var temp = (object) newComp; _serializationManager.CopyTo(data.Component, ref temp); EntityManager.AddComponent(uid, (Component)temp!); } } private void OnCompUnequip(EntityUid uid, ClothingGrantComponentComponent component, GotUnequippedEvent args) { if (!component.IsActive) return; foreach (var (name, data) in component.Components) { var newComp = (Component) _componentFactory.GetComponent(name); RemComp(args.Equipee, newComp.GetType()); } component.IsActive = false; Dirty(uid, component); } private void OnTagEquip(EntityUid uid, ClothingGrantTagComponent component, GotEquippedEvent args) { if (!TryComp(uid, out var clothing)) return; if (!clothing.Slots.HasFlag(args.SlotFlags)) return; EnsureComp(args.Equipee); _tagSystem.AddTag(args.Equipee, component.Tag); component.IsActive = true; Dirty(uid, component); } private void OnTagUnequip(EntityUid uid, ClothingGrantTagComponent component, GotUnequippedEvent args) { if (!component.IsActive) return; _tagSystem.RemoveTag(args.Equipee, component.Tag); component.IsActive = false; Dirty(uid, component); } }