WeldableSystem.cs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. using Content.Shared.Administration.Logs;
  2. using Content.Shared.Database;
  3. using Content.Shared.Examine;
  4. using Content.Shared.Interaction;
  5. using Content.Shared.Tools.Components;
  6. using Robust.Shared.Physics;
  7. using Robust.Shared.Physics.Systems;
  8. using LayerChangeOnWeldComponent = Content.Shared.Tools.Components.LayerChangeOnWeldComponent;
  9. namespace Content.Shared.Tools.Systems;
  10. public sealed class WeldableSystem : EntitySystem
  11. {
  12. [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
  13. [Dependency] private readonly SharedToolSystem _toolSystem = default!;
  14. [Dependency] private readonly SharedAppearanceSystem _appearance = default!;
  15. [Dependency] private readonly SharedPhysicsSystem _physics = default!;
  16. private EntityQuery<WeldableComponent> _query;
  17. public override void Initialize()
  18. {
  19. base.Initialize();
  20. SubscribeLocalEvent<WeldableComponent, InteractUsingEvent>(OnInteractUsing);
  21. SubscribeLocalEvent<WeldableComponent, WeldFinishedEvent>(OnWeldFinished);
  22. SubscribeLocalEvent<LayerChangeOnWeldComponent, WeldableChangedEvent>(OnWeldChanged);
  23. SubscribeLocalEvent<WeldableComponent, ExaminedEvent>(OnExamine);
  24. _query = GetEntityQuery<WeldableComponent>();
  25. }
  26. public bool IsWelded(EntityUid uid, WeldableComponent? component = null)
  27. {
  28. return _query.Resolve(uid, ref component, false) && component.IsWelded;
  29. }
  30. private void OnExamine(EntityUid uid, WeldableComponent component, ExaminedEvent args)
  31. {
  32. if (component.IsWelded && component.WeldedExamineMessage != null)
  33. args.PushText(Loc.GetString(component.WeldedExamineMessage));
  34. }
  35. private void OnInteractUsing(EntityUid uid, WeldableComponent component, InteractUsingEvent args)
  36. {
  37. if (args.Handled)
  38. return;
  39. args.Handled = TryWeld(uid, args.Used, args.User, component);
  40. }
  41. private bool CanWeld(EntityUid uid, EntityUid tool, EntityUid user, WeldableComponent? component = null)
  42. {
  43. if (!_query.Resolve(uid, ref component))
  44. return false;
  45. // Other component systems
  46. var attempt = new WeldableAttemptEvent(user, tool);
  47. RaiseLocalEvent(uid, attempt);
  48. if (attempt.Cancelled)
  49. return false;
  50. return true;
  51. }
  52. private bool TryWeld(EntityUid uid, EntityUid tool, EntityUid user, WeldableComponent? component = null)
  53. {
  54. if (!_query.Resolve(uid, ref component))
  55. return false;
  56. if (!CanWeld(uid, tool, user, component))
  57. return false;
  58. if (!_toolSystem.UseTool(tool, user, uid, component.Time.Seconds, component.WeldingQuality, new WeldFinishedEvent(), component.Fuel))
  59. return false;
  60. // Log attempt
  61. _adminLogger.Add(LogType.Action, LogImpact.Low, $"{ToPrettyString(user):user} is {(component.IsWelded ? "un" : "")}welding {ToPrettyString(uid):target} at {Transform(uid).Coordinates:targetlocation}");
  62. return true;
  63. }
  64. private void OnWeldFinished(EntityUid uid, WeldableComponent component, WeldFinishedEvent args)
  65. {
  66. if (args.Cancelled || args.Used == null)
  67. return;
  68. // Check if target is still valid
  69. if (!CanWeld(uid, args.Used.Value, args.User, component))
  70. return;
  71. SetWeldedState(uid, !component.IsWelded, component);
  72. // Log success
  73. _adminLogger.Add(LogType.Action, LogImpact.Low, $"{ToPrettyString(args.User):user} {(!component.IsWelded ? "un" : "")}welded {ToPrettyString(uid):target}");
  74. }
  75. private void OnWeldChanged(EntityUid uid, LayerChangeOnWeldComponent component, ref WeldableChangedEvent args)
  76. {
  77. if (!TryComp<FixturesComponent>(uid, out var fixtures))
  78. return;
  79. foreach (var (id, fixture) in fixtures.Fixtures)
  80. {
  81. switch (args.IsWelded)
  82. {
  83. case true when fixture.CollisionLayer == (int) component.UnWeldedLayer:
  84. _physics.SetCollisionLayer(uid, id, fixture, (int) component.WeldedLayer);
  85. break;
  86. case false when fixture.CollisionLayer == (int) component.WeldedLayer:
  87. _physics.SetCollisionLayer(uid, id, fixture, (int) component.UnWeldedLayer);
  88. break;
  89. }
  90. }
  91. }
  92. private void UpdateAppearance(EntityUid uid, WeldableComponent? component = null)
  93. {
  94. if (_query.Resolve(uid, ref component))
  95. _appearance.SetData(uid, WeldableVisuals.IsWelded, component.IsWelded);
  96. }
  97. public void SetWeldedState(EntityUid uid, bool state, WeldableComponent? component = null)
  98. {
  99. if (!_query.Resolve(uid, ref component))
  100. return;
  101. if (component.IsWelded == state)
  102. return;
  103. component.IsWelded = state;
  104. var ev = new WeldableChangedEvent(component.IsWelded);
  105. RaiseLocalEvent(uid, ref ev);
  106. UpdateAppearance(uid, component);
  107. Dirty(uid, component);
  108. }
  109. public void SetWeldingTime(EntityUid uid, TimeSpan time, WeldableComponent? component = null)
  110. {
  111. if (!_query.Resolve(uid, ref component))
  112. return;
  113. if (component.Time.Equals(time))
  114. return;
  115. component.Time = time;
  116. Dirty(uid, component);
  117. }
  118. }