using Content.Shared.CombatMode; using Content.Shared.DragDrop; using Content.Shared.Hands.Components; using Content.Shared.Interaction; using Content.Shared.Interaction.Components; using Content.Shared.Inventory; using Content.Shared.Popups; using Content.Shared.Strip.Components; namespace Content.Shared.Strip; public abstract class SharedStrippableSystem : EntitySystem { [Dependency] private readonly SharedPopupSystem _popup = default!; [Dependency] private readonly SharedUserInterfaceSystem _ui = default!; [Dependency] private readonly ThievingSystem _thieving = default!; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnCanDropOn); SubscribeLocalEvent(OnCanDrop); SubscribeLocalEvent(OnDragDrop); SubscribeLocalEvent(OnActivateInWorld); } private void OnActivateInWorld(EntityUid uid, StrippableComponent component, ActivateInWorldEvent args) { if (args.Handled || !args.Complex || args.Target == args.User) return; if (TryOpenStrippingUi(args.User, (uid, component))) args.Handled = true; } /// /// Modify the strip time via events. Raised directed at the item being stripped, the player stripping someone and the player being stripped. /// public (TimeSpan Time, ThievingStealth Stealth) GetStripTimeModifiers(EntityUid user, EntityUid targetPlayer, EntityUid? targetItem, TimeSpan initialTime) { var itemEv = new BeforeItemStrippedEvent(initialTime); if (targetItem != null) RaiseLocalEvent(targetItem.Value, ref itemEv); var userEv = new BeforeStripEvent(itemEv.Time, itemEv.Stealth); RaiseLocalEvent(user, ref userEv); var targetEv = new BeforeGettingStrippedEvent(userEv.Time, userEv.Stealth); RaiseLocalEvent(targetPlayer, ref targetEv); return (targetEv.Time, targetEv.Stealth); } private void OnDragDrop(EntityUid uid, StrippableComponent component, ref DragDropDraggedEvent args) { // If the user drags a strippable thing onto themselves. if (args.Handled || args.Target != args.User) return; if (TryOpenStrippingUi(args.User, (uid, component))) args.Handled = true; } public bool TryOpenStrippingUi(EntityUid user, Entity target, bool openInCombat = false) { if (!openInCombat && TryComp(user, out var mode) && mode.IsInCombatMode) return false; if (!HasComp(user)) return false; _ui.OpenUi(target.Owner, StrippingUiKey.Key, user); return true; } private void OnCanDropOn(EntityUid uid, StrippingComponent component, ref CanDropTargetEvent args) { var val = uid == args.User && HasComp(args.Dragged) && HasComp(args.User) && HasComp(args.User); args.Handled |= val; args.CanDrop |= val; } private void OnCanDrop(EntityUid uid, StrippableComponent component, ref CanDropDraggedEvent args) { args.CanDrop |= args.Target == args.User && HasComp(args.User) && HasComp(args.User); if (args.CanDrop) args.Handled = true; } public void StripPopup(string messageId, ThievingStealth stealth, EntityUid target, EntityUid? user = null, EntityUid? item = null, string slot = "") { bool subtle = stealth == ThievingStealth.Subtle; PopupType? popupSize = _thieving.GetPopupTypeFromStealth(stealth); if (popupSize.HasValue) // We should always have a value if we're not hidden _popup.PopupEntity( Loc.GetString( messageId, ("user", subtle ? Loc.GetString("thieving-component-user") : user ?? EntityUid.Invalid), ("item", subtle ? Loc.GetString("thieving-component-item") : item ?? EntityUid.Invalid), ("slot", slot)), target, target, popupSize.Value); } public bool IsStripHidden(SlotDefinition definition, EntityUid? viewer) { if (!definition.StripHidden) return false; if (viewer == null) return true; return !(HasComp(viewer) || HasComp(viewer)); } }