EscapeInventorySystem.cs 3.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. using Content.Server.Popups;
  2. using Content.Shared.Storage.Components;
  3. using Content.Shared.ActionBlocker;
  4. using Content.Shared.DoAfter;
  5. using Content.Shared.Hands.EntitySystems;
  6. using Content.Shared.Interaction.Events;
  7. using Content.Shared.Inventory;
  8. using Content.Shared.Movement.Events;
  9. using Content.Shared.Resist;
  10. using Content.Shared.Storage;
  11. using Robust.Shared.Containers;
  12. namespace Content.Server.Resist;
  13. public sealed class EscapeInventorySystem : EntitySystem
  14. {
  15. [Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!;
  16. [Dependency] private readonly PopupSystem _popupSystem = default!;
  17. [Dependency] private readonly SharedContainerSystem _containerSystem = default!;
  18. [Dependency] private readonly ActionBlockerSystem _actionBlockerSystem = default!;
  19. [Dependency] private readonly SharedHandsSystem _handsSystem = default!;
  20. public override void Initialize()
  21. {
  22. base.Initialize();
  23. SubscribeLocalEvent<CanEscapeInventoryComponent, MoveInputEvent>(OnRelayMovement);
  24. SubscribeLocalEvent<CanEscapeInventoryComponent, EscapeInventoryEvent>(OnEscape);
  25. SubscribeLocalEvent<CanEscapeInventoryComponent, DroppedEvent>(OnDropped);
  26. }
  27. private void OnRelayMovement(EntityUid uid, CanEscapeInventoryComponent component, ref MoveInputEvent args)
  28. {
  29. if (!args.HasDirectionalMovement)
  30. return;
  31. if (!_containerSystem.TryGetContainingContainer((uid, null, null), out var container) || !_actionBlockerSystem.CanInteract(uid, container.Owner))
  32. return;
  33. // Make sure there's nothing stopped the removal (like being glued)
  34. if (!_containerSystem.CanRemove(uid, container))
  35. {
  36. _popupSystem.PopupEntity(Loc.GetString("escape-inventory-component-failed-resisting"), uid, uid);
  37. return;
  38. }
  39. // Contested
  40. if (_handsSystem.IsHolding(container.Owner, uid, out _))
  41. {
  42. AttemptEscape(uid, container.Owner, component);
  43. return;
  44. }
  45. // Uncontested
  46. if (HasComp<StorageComponent>(container.Owner) || HasComp<InventoryComponent>(container.Owner) || HasComp<SecretStashComponent>(container.Owner))
  47. AttemptEscape(uid, container.Owner, component);
  48. }
  49. private void AttemptEscape(EntityUid user, EntityUid container, CanEscapeInventoryComponent component, float multiplier = 1f)
  50. {
  51. if (component.IsEscaping)
  52. return;
  53. var doAfterEventArgs = new DoAfterArgs(EntityManager, user, component.BaseResistTime * multiplier, new EscapeInventoryEvent(), user, target: container)
  54. {
  55. BreakOnMove = true,
  56. BreakOnDamage = true,
  57. NeedHand = false
  58. };
  59. if (!_doAfterSystem.TryStartDoAfter(doAfterEventArgs, out component.DoAfter))
  60. return;
  61. _popupSystem.PopupEntity(Loc.GetString("escape-inventory-component-start-resisting"), user, user);
  62. _popupSystem.PopupEntity(Loc.GetString("escape-inventory-component-start-resisting-target"), container, container);
  63. }
  64. private void OnEscape(EntityUid uid, CanEscapeInventoryComponent component, EscapeInventoryEvent args)
  65. {
  66. component.DoAfter = null;
  67. if (args.Handled || args.Cancelled)
  68. return;
  69. _containerSystem.AttachParentToContainerOrGrid((uid, Transform(uid)));
  70. args.Handled = true;
  71. }
  72. private void OnDropped(EntityUid uid, CanEscapeInventoryComponent component, DroppedEvent args)
  73. {
  74. if (component.DoAfter != null)
  75. _doAfterSystem.Cancel(component.DoAfter);
  76. }
  77. }