using Content.Server.IdentityManagement; using Content.Shared.Clothing.Components; using Content.Shared.Clothing.EntitySystems; using Content.Shared.IdentityManagement.Components; using Content.Shared.Prototypes; using Content.Shared.Verbs; using Robust.Server.GameObjects; using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Utility; namespace Content.Server.Clothing.Systems; public sealed class ChameleonClothingSystem : SharedChameleonClothingSystem { [Dependency] private readonly IPrototypeManager _proto = default!; [Dependency] private readonly UserInterfaceSystem _uiSystem = default!; [Dependency] private readonly IComponentFactory _factory = default!; [Dependency] private readonly IdentitySystem _identity = default!; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnMapInit); SubscribeLocalEvent>(OnVerb); SubscribeLocalEvent(OnSelected); } private void OnMapInit(EntityUid uid, ChameleonClothingComponent component, MapInitEvent args) { SetSelectedPrototype(uid, component.Default, true, component); } private void OnVerb(EntityUid uid, ChameleonClothingComponent component, GetVerbsEvent args) { if (!args.CanAccess || !args.CanInteract || component.User != args.User) return; args.Verbs.Add(new InteractionVerb() { Text = Loc.GetString("chameleon-component-verb-text"), Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/settings.svg.192dpi.png")), Act = () => TryOpenUi(uid, args.User, component) }); } private void OnSelected(EntityUid uid, ChameleonClothingComponent component, ChameleonPrototypeSelectedMessage args) { SetSelectedPrototype(uid, args.SelectedId, component: component); } private void TryOpenUi(EntityUid uid, EntityUid user, ChameleonClothingComponent? component = null) { if (!Resolve(uid, ref component)) return; if (!TryComp(user, out ActorComponent? actor)) return; _uiSystem.TryToggleUi(uid, ChameleonUiKey.Key, actor.PlayerSession); } private void UpdateUi(EntityUid uid, ChameleonClothingComponent? component = null) { if (!Resolve(uid, ref component)) return; var state = new ChameleonBoundUserInterfaceState(component.Slot, component.Default); _uiSystem.SetUiState(uid, ChameleonUiKey.Key, state); } /// /// Change chameleon items name, description and sprite to mimic other entity prototype. /// public void SetSelectedPrototype(EntityUid uid, string? protoId, bool forceUpdate = false, ChameleonClothingComponent? component = null) { if (!Resolve(uid, ref component, false)) return; // check that wasn't already selected // forceUpdate on component init ignores this check if (component.Default == protoId && !forceUpdate) return; // make sure that it is valid change if (string.IsNullOrEmpty(protoId) || !_proto.TryIndex(protoId, out EntityPrototype? proto)) return; if (!IsValidTarget(proto, component.Slot)) return; component.Default = protoId; UpdateIdentityBlocker(uid, component, proto); UpdateVisuals(uid, component); UpdateUi(uid, component); Dirty(uid, component); } private void UpdateIdentityBlocker(EntityUid uid, ChameleonClothingComponent component, EntityPrototype proto) { if (proto.HasComponent(_factory)) EnsureComp(uid); else RemComp(uid); if (component.User != null) _identity.QueueIdentityUpdate(component.User.Value); } }