FrictionContactsSystem.cs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. using Content.Shared.Movement.Components;
  2. using Robust.Shared.Physics.Components;
  3. using Robust.Shared.Physics.Events;
  4. using Robust.Shared.Physics.Systems;
  5. namespace Content.Shared.Movement.Systems;
  6. public sealed class FrictionContactsSystem : EntitySystem
  7. {
  8. [Dependency] private readonly SharedPhysicsSystem _physics = default!;
  9. [Dependency] private readonly MovementSpeedModifierSystem _speedModifierSystem = default!;
  10. // Comment copied from "original" SlowContactsSystem.cs (now SpeedModifierContactsSystem.cs)
  11. // TODO full-game-save
  12. // Either these need to be processed before a map is saved, or slowed/slowing entities need to update on init.
  13. private HashSet<EntityUid> _toUpdate = new();
  14. public override void Initialize()
  15. {
  16. base.Initialize();
  17. SubscribeLocalEvent<FrictionContactsComponent, StartCollideEvent>(OnEntityEnter);
  18. SubscribeLocalEvent<FrictionContactsComponent, EndCollideEvent>(OnEntityExit);
  19. SubscribeLocalEvent<FrictionContactsComponent, ComponentShutdown>(OnShutdown);
  20. UpdatesAfter.Add(typeof(SharedPhysicsSystem));
  21. }
  22. private void OnEntityEnter(EntityUid uid, FrictionContactsComponent component, ref StartCollideEvent args)
  23. {
  24. var otherUid = args.OtherEntity;
  25. if (!HasComp(otherUid, typeof(MovementSpeedModifierComponent)))
  26. return;
  27. _toUpdate.Add(otherUid);
  28. }
  29. private void OnEntityExit(EntityUid uid, FrictionContactsComponent component, ref EndCollideEvent args)
  30. {
  31. var otherUid = args.OtherEntity;
  32. if (!HasComp(otherUid, typeof(MovementSpeedModifierComponent)))
  33. return;
  34. _toUpdate.Add(otherUid);
  35. }
  36. private void OnShutdown(EntityUid uid, FrictionContactsComponent component, ComponentShutdown args)
  37. {
  38. if (!TryComp(uid, out PhysicsComponent? phys))
  39. return;
  40. _toUpdate.UnionWith(_physics.GetContactingEntities(uid, phys));
  41. }
  42. public override void Update(float frameTime)
  43. {
  44. base.Update(frameTime);
  45. foreach (var uid in _toUpdate)
  46. {
  47. ApplyFrictionChange(uid);
  48. }
  49. _toUpdate.Clear();
  50. }
  51. private void ApplyFrictionChange(EntityUid uid)
  52. {
  53. if (!EntityManager.TryGetComponent<PhysicsComponent>(uid, out var physicsComponent))
  54. return;
  55. if (!TryComp(uid, out MovementSpeedModifierComponent? speedModifier))
  56. return;
  57. FrictionContactsComponent? frictionComponent = TouchesFrictionContactsComponent(uid, physicsComponent);
  58. if (frictionComponent == null)
  59. {
  60. _speedModifierSystem.ChangeFriction(uid, MovementSpeedModifierComponent.DefaultFriction, null, MovementSpeedModifierComponent.DefaultAcceleration, speedModifier);
  61. }
  62. else
  63. {
  64. _speedModifierSystem.ChangeFriction(uid, frictionComponent.MobFriction, frictionComponent.MobFrictionNoInput, frictionComponent.MobAcceleration, speedModifier);
  65. }
  66. }
  67. private FrictionContactsComponent? TouchesFrictionContactsComponent(EntityUid uid, PhysicsComponent physicsComponent)
  68. {
  69. foreach (var ent in _physics.GetContactingEntities(uid, physicsComponent))
  70. {
  71. if (!TryComp(ent, out FrictionContactsComponent? frictionContacts))
  72. continue;
  73. return frictionContacts;
  74. }
  75. return null;
  76. }
  77. }