1
0

ClothingSpeedModifierSystem.cs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. using Content.Shared.Examine;
  2. using Content.Shared.Inventory;
  3. using Content.Shared.Item.ItemToggle;
  4. using Content.Shared.Item.ItemToggle.Components;
  5. using Content.Shared.Movement.Systems;
  6. using Content.Shared.Verbs;
  7. using Robust.Shared.Containers;
  8. using Robust.Shared.GameStates;
  9. using Robust.Shared.Utility;
  10. namespace Content.Shared.Clothing;
  11. public sealed class ClothingSpeedModifierSystem : EntitySystem
  12. {
  13. [Dependency] private readonly SharedContainerSystem _container = default!;
  14. [Dependency] private readonly ExamineSystemShared _examine = default!;
  15. [Dependency] private readonly MovementSpeedModifierSystem _movementSpeed = default!;
  16. [Dependency] private readonly ItemToggleSystem _toggle = default!;
  17. public override void Initialize()
  18. {
  19. base.Initialize();
  20. SubscribeLocalEvent<ClothingSpeedModifierComponent, ComponentGetState>(OnGetState);
  21. SubscribeLocalEvent<ClothingSpeedModifierComponent, ComponentHandleState>(OnHandleState);
  22. SubscribeLocalEvent<ClothingSpeedModifierComponent, InventoryRelayedEvent<RefreshMovementSpeedModifiersEvent>>(OnRefreshMoveSpeed);
  23. SubscribeLocalEvent<ClothingSpeedModifierComponent, GetVerbsEvent<ExamineVerb>>(OnClothingVerbExamine);
  24. SubscribeLocalEvent<ClothingSpeedModifierComponent, ItemToggledEvent>(OnToggled);
  25. }
  26. private void OnGetState(EntityUid uid, ClothingSpeedModifierComponent component, ref ComponentGetState args)
  27. {
  28. args.State = new ClothingSpeedModifierComponentState(component.WalkModifier, component.SprintModifier);
  29. }
  30. private void OnHandleState(EntityUid uid, ClothingSpeedModifierComponent component, ref ComponentHandleState args)
  31. {
  32. if (args.Current is not ClothingSpeedModifierComponentState state)
  33. return;
  34. var diff = !MathHelper.CloseTo(component.SprintModifier, state.SprintModifier) ||
  35. !MathHelper.CloseTo(component.WalkModifier, state.WalkModifier);
  36. component.WalkModifier = state.WalkModifier;
  37. component.SprintModifier = state.SprintModifier;
  38. // Avoid raising the event for the container if nothing changed.
  39. // We'll still set the values in case they're slightly different but within tolerance.
  40. if (diff && _container.TryGetContainingContainer((uid, null, null), out var container))
  41. {
  42. _movementSpeed.RefreshMovementSpeedModifiers(container.Owner);
  43. }
  44. }
  45. private void OnRefreshMoveSpeed(EntityUid uid, ClothingSpeedModifierComponent component, InventoryRelayedEvent<RefreshMovementSpeedModifiersEvent> args)
  46. {
  47. if (_toggle.IsActivated(uid))
  48. args.Args.ModifySpeed(component.WalkModifier, component.SprintModifier);
  49. }
  50. private void OnClothingVerbExamine(EntityUid uid, ClothingSpeedModifierComponent component, GetVerbsEvent<ExamineVerb> args)
  51. {
  52. if (!args.CanInteract || !args.CanAccess)
  53. return;
  54. var walkModifierPercentage = MathF.Round((1.0f - component.WalkModifier) * 100f, 1);
  55. var sprintModifierPercentage = MathF.Round((1.0f - component.SprintModifier) * 100f, 1);
  56. if (walkModifierPercentage == 0.0f && sprintModifierPercentage == 0.0f)
  57. return;
  58. var msg = new FormattedMessage();
  59. if (MathHelper.CloseTo(walkModifierPercentage, sprintModifierPercentage, 0.5f))
  60. {
  61. if (walkModifierPercentage < 0.0f)
  62. msg.AddMarkupOrThrow(Loc.GetString("clothing-speed-increase-equal-examine", ("walkSpeed", (int) MathF.Abs(walkModifierPercentage)), ("runSpeed", (int) MathF.Abs(sprintModifierPercentage))));
  63. else
  64. msg.AddMarkupOrThrow(Loc.GetString("clothing-speed-decrease-equal-examine", ("walkSpeed", (int) walkModifierPercentage), ("runSpeed", (int) sprintModifierPercentage)));
  65. }
  66. else
  67. {
  68. if (sprintModifierPercentage < 0.0f)
  69. {
  70. msg.AddMarkupOrThrow(Loc.GetString("clothing-speed-increase-run-examine", ("runSpeed", (int) MathF.Abs(sprintModifierPercentage))));
  71. }
  72. else if (sprintModifierPercentage > 0.0f)
  73. {
  74. msg.AddMarkupOrThrow(Loc.GetString("clothing-speed-decrease-run-examine", ("runSpeed", (int) sprintModifierPercentage)));
  75. }
  76. if (walkModifierPercentage != 0.0f && sprintModifierPercentage != 0.0f)
  77. {
  78. msg.PushNewline();
  79. }
  80. if (walkModifierPercentage < 0.0f)
  81. {
  82. msg.AddMarkupOrThrow(Loc.GetString("clothing-speed-increase-walk-examine", ("walkSpeed", (int) MathF.Abs(walkModifierPercentage))));
  83. }
  84. else if (walkModifierPercentage > 0.0f)
  85. {
  86. msg.AddMarkupOrThrow(Loc.GetString("clothing-speed-decrease-walk-examine", ("walkSpeed", (int) walkModifierPercentage)));
  87. }
  88. }
  89. _examine.AddDetailedExamineVerb(args, component, msg, Loc.GetString("clothing-speed-examinable-verb-text"), "/Textures/Interface/VerbIcons/outfit.svg.192dpi.png", Loc.GetString("clothing-speed-examinable-verb-message"));
  90. }
  91. private void OnToggled(Entity<ClothingSpeedModifierComponent> ent, ref ItemToggledEvent args)
  92. {
  93. // make sentient boots slow or fast too
  94. _movementSpeed.RefreshMovementSpeedModifiers(ent);
  95. if (_container.TryGetContainingContainer((ent.Owner, null, null), out var container))
  96. {
  97. // inventory system will automatically hook into the event raised by this and update accordingly
  98. _movementSpeed.RefreshMovementSpeedModifiers(container.Owner);
  99. }
  100. }
  101. }