1
0

SharedInjectorSystem.cs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. using Content.Shared.Administration.Logs;
  2. using Content.Shared.Chemistry.Components;
  3. using Content.Shared.CombatMode;
  4. using Content.Shared.DoAfter;
  5. using Content.Shared.FixedPoint;
  6. using Content.Shared.Interaction.Events;
  7. using Content.Shared.Mobs.Systems;
  8. using Content.Shared.Popups;
  9. using Content.Shared.Verbs;
  10. using Robust.Shared.Player;
  11. namespace Content.Shared.Chemistry.EntitySystems;
  12. public abstract class SharedInjectorSystem : EntitySystem
  13. {
  14. /// <summary>
  15. /// Default transfer amounts for the set-transfer verb.
  16. /// </summary>
  17. public static readonly FixedPoint2[] TransferAmounts = { 1, 5, 10, 15 };
  18. [Dependency] protected readonly SharedPopupSystem Popup = default!;
  19. [Dependency] protected readonly SharedSolutionContainerSystem SolutionContainers = default!;
  20. [Dependency] protected readonly MobStateSystem MobState = default!;
  21. [Dependency] protected readonly SharedCombatModeSystem Combat = default!;
  22. [Dependency] protected readonly SharedDoAfterSystem DoAfter = default!;
  23. [Dependency] protected readonly ISharedAdminLogManager AdminLogger = default!;
  24. public override void Initialize()
  25. {
  26. SubscribeLocalEvent<InjectorComponent, GetVerbsEvent<AlternativeVerb>>(AddSetTransferVerbs);
  27. SubscribeLocalEvent<InjectorComponent, ComponentStartup>(OnInjectorStartup);
  28. SubscribeLocalEvent<InjectorComponent, UseInHandEvent>(OnInjectorUse);
  29. }
  30. private void AddSetTransferVerbs(Entity<InjectorComponent> entity, ref GetVerbsEvent<AlternativeVerb> args)
  31. {
  32. if (!args.CanAccess || !args.CanInteract || args.Hands == null)
  33. return;
  34. var user = args.User;
  35. var (_, component) = entity;
  36. var min = component.MinimumTransferAmount;
  37. var max = component.MaximumTransferAmount;
  38. var cur = component.TransferAmount;
  39. var toggleAmount = cur == max ? min : max;
  40. var priority = 0;
  41. AlternativeVerb toggleVerb = new()
  42. {
  43. Text = Loc.GetString("comp-solution-transfer-verb-toggle", ("amount", toggleAmount)),
  44. Category = VerbCategory.SetTransferAmount,
  45. Act = () =>
  46. {
  47. component.TransferAmount = toggleAmount;
  48. Popup.PopupClient(Loc.GetString("comp-solution-transfer-set-amount", ("amount", toggleAmount)), user, user);
  49. Dirty(entity);
  50. },
  51. Priority = priority
  52. };
  53. args.Verbs.Add(toggleVerb);
  54. priority -= 1;
  55. // Add specific transfer verbs according to the container's size
  56. foreach (var amount in TransferAmounts)
  57. {
  58. if (amount < component.MinimumTransferAmount || amount > component.MaximumTransferAmount)
  59. continue;
  60. AlternativeVerb verb = new()
  61. {
  62. Text = Loc.GetString("comp-solution-transfer-verb-amount", ("amount", amount)),
  63. Category = VerbCategory.SetTransferAmount,
  64. Act = () =>
  65. {
  66. component.TransferAmount = amount;
  67. Popup.PopupClient(Loc.GetString("comp-solution-transfer-set-amount", ("amount", amount)), user, user);
  68. Dirty(entity);
  69. },
  70. // we want to sort by size, not alphabetically by the verb text.
  71. Priority = priority
  72. };
  73. priority -= 1;
  74. args.Verbs.Add(verb);
  75. }
  76. }
  77. private void OnInjectorStartup(Entity<InjectorComponent> entity, ref ComponentStartup args)
  78. {
  79. // ???? why ?????
  80. Dirty(entity);
  81. }
  82. private void OnInjectorUse(Entity<InjectorComponent> entity, ref UseInHandEvent args)
  83. {
  84. if (args.Handled)
  85. return;
  86. Toggle(entity, args.User);
  87. args.Handled = true;
  88. }
  89. /// <summary>
  90. /// Toggle between draw/inject state if applicable
  91. /// </summary>
  92. private void Toggle(Entity<InjectorComponent> injector, EntityUid user)
  93. {
  94. if (injector.Comp.InjectOnly)
  95. return;
  96. if (!SolutionContainers.TryGetSolution(injector.Owner, injector.Comp.SolutionName, out var solEnt, out var solution))
  97. return;
  98. string msg;
  99. switch (injector.Comp.ToggleState)
  100. {
  101. case InjectorToggleMode.Inject:
  102. if (solution.AvailableVolume > 0) // If solution has empty space to fill up, allow toggling to draw
  103. {
  104. SetMode(injector, InjectorToggleMode.Draw);
  105. msg = "injector-component-drawing-text";
  106. }
  107. else
  108. {
  109. msg = "injector-component-cannot-toggle-draw-message";
  110. }
  111. break;
  112. case InjectorToggleMode.Draw:
  113. if (solution.Volume > 0) // If solution has anything in it, allow toggling to inject
  114. {
  115. SetMode(injector, InjectorToggleMode.Inject);
  116. msg = "injector-component-injecting-text";
  117. }
  118. else
  119. {
  120. msg = "injector-component-cannot-toggle-inject-message";
  121. }
  122. break;
  123. default:
  124. throw new ArgumentOutOfRangeException();
  125. }
  126. Popup.PopupClient(Loc.GetString(msg), injector, user);
  127. }
  128. public void SetMode(Entity<InjectorComponent> injector, InjectorToggleMode mode)
  129. {
  130. injector.Comp.ToggleState = mode;
  131. Dirty(injector);
  132. }
  133. }