TwoWayLeverSystem.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. using Content.Shared.DeviceLinking.Components;
  2. using Content.Shared.Interaction;
  3. using Content.Shared.Verbs;
  4. using Robust.Shared.Utility;
  5. namespace Content.Shared.DeviceLinking.Systems
  6. {
  7. public sealed class TwoWayLeverSystem : EntitySystem
  8. {
  9. [Dependency] private readonly SharedDeviceLinkSystem _signalSystem = default!;
  10. [Dependency] private readonly SharedAppearanceSystem _appearance = default!;
  11. const string _leftToggleImage = "rotate_ccw.svg.192dpi.png";
  12. const string _rightToggleImage = "rotate_cw.svg.192dpi.png";
  13. public override void Initialize()
  14. {
  15. base.Initialize();
  16. SubscribeLocalEvent<TwoWayLeverComponent, ComponentInit>(OnInit);
  17. SubscribeLocalEvent<TwoWayLeverComponent, ActivateInWorldEvent>(OnActivated);
  18. SubscribeLocalEvent<TwoWayLeverComponent, GetVerbsEvent<InteractionVerb>>(OnGetInteractionVerbs);
  19. }
  20. private void OnInit(EntityUid uid, TwoWayLeverComponent component, ComponentInit args)
  21. {
  22. _signalSystem.EnsureSourcePorts(uid, component.LeftPort, component.RightPort, component.MiddlePort);
  23. }
  24. private void OnActivated(EntityUid uid, TwoWayLeverComponent component, ActivateInWorldEvent args)
  25. {
  26. if (args.Handled || !args.Complex)
  27. return;
  28. component.State = component.State switch
  29. {
  30. TwoWayLeverState.Middle => component.NextSignalLeft ? TwoWayLeverState.Left : TwoWayLeverState.Right,
  31. TwoWayLeverState.Right => TwoWayLeverState.Middle,
  32. TwoWayLeverState.Left => TwoWayLeverState.Middle,
  33. _ => throw new ArgumentOutOfRangeException()
  34. };
  35. StateChanged(uid, component);
  36. args.Handled = true;
  37. }
  38. private void OnGetInteractionVerbs(EntityUid uid, TwoWayLeverComponent component, GetVerbsEvent<InteractionVerb> args)
  39. {
  40. if (!args.CanAccess || !args.CanInteract || (args.Hands == null))
  41. return;
  42. var disabled = component.State == TwoWayLeverState.Left;
  43. InteractionVerb verbLeft = new()
  44. {
  45. Act = () =>
  46. {
  47. component.State = component.State switch
  48. {
  49. TwoWayLeverState.Middle => TwoWayLeverState.Left,
  50. TwoWayLeverState.Right => TwoWayLeverState.Middle,
  51. _ => throw new ArgumentOutOfRangeException()
  52. };
  53. StateChanged(uid, component);
  54. },
  55. Category = VerbCategory.Lever,
  56. Message = disabled ? Loc.GetString("two-way-lever-cant") : null,
  57. Disabled = disabled,
  58. Icon = new SpriteSpecifier.Texture(new ($"/Textures/Interface/VerbIcons/{_leftToggleImage}")),
  59. Text = Loc.GetString("two-way-lever-left"),
  60. };
  61. args.Verbs.Add(verbLeft);
  62. disabled = component.State == TwoWayLeverState.Right;
  63. InteractionVerb verbRight = new()
  64. {
  65. Act = () =>
  66. {
  67. component.State = component.State switch
  68. {
  69. TwoWayLeverState.Left => TwoWayLeverState.Middle,
  70. TwoWayLeverState.Middle => TwoWayLeverState.Right,
  71. _ => throw new ArgumentOutOfRangeException()
  72. };
  73. StateChanged(uid, component);
  74. },
  75. Category = VerbCategory.Lever,
  76. Message = disabled ? Loc.GetString("two-way-lever-cant") : null,
  77. Disabled = disabled,
  78. Icon = new SpriteSpecifier.Texture(new ($"/Textures/Interface/VerbIcons/{_rightToggleImage}")),
  79. Text = Loc.GetString("two-way-lever-right"),
  80. };
  81. args.Verbs.Add(verbRight);
  82. }
  83. private void StateChanged(EntityUid uid, TwoWayLeverComponent component)
  84. {
  85. if (component.State == TwoWayLeverState.Middle)
  86. component.NextSignalLeft = !component.NextSignalLeft;
  87. if (TryComp(uid, out AppearanceComponent? appearance))
  88. _appearance.SetData(uid, TwoWayLeverVisuals.State, component.State, appearance);
  89. var port = component.State switch
  90. {
  91. TwoWayLeverState.Left => component.LeftPort,
  92. TwoWayLeverState.Right => component.RightPort,
  93. TwoWayLeverState.Middle => component.MiddlePort,
  94. _ => throw new ArgumentOutOfRangeException()
  95. };
  96. Dirty(uid, component);
  97. _signalSystem.InvokePort(uid, port);
  98. }
  99. }
  100. }