SharedMouseRotatorSystem.cs 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. using Content.Shared.Interaction;
  2. namespace Content.Shared.MouseRotator;
  3. /// <summary>
  4. /// This handles rotating an entity based on mouse location
  5. /// </summary>
  6. /// <see cref="MouseRotatorComponent"/>
  7. public abstract class SharedMouseRotatorSystem : EntitySystem
  8. {
  9. [Dependency] private readonly RotateToFaceSystem _rotate = default!;
  10. public override void Initialize()
  11. {
  12. base.Initialize();
  13. SubscribeAllEvent<RequestMouseRotatorRotationEvent>(OnRequestRotation);
  14. }
  15. public override void Update(float frameTime)
  16. {
  17. base.Update(frameTime);
  18. // TODO maybe `ActiveMouseRotatorComponent` to avoid querying over more entities than we need?
  19. // (if this is added to players)
  20. // (but arch makes these fast anyway, so)
  21. var query = EntityQueryEnumerator<MouseRotatorComponent, TransformComponent>();
  22. while (query.MoveNext(out var uid, out var rotator, out var xform))
  23. {
  24. if (rotator.GoalRotation == null)
  25. continue;
  26. if (_rotate.TryRotateTo(
  27. uid,
  28. rotator.GoalRotation.Value,
  29. frameTime,
  30. rotator.AngleTolerance,
  31. MathHelper.DegreesToRadians(rotator.RotationSpeed),
  32. xform))
  33. {
  34. // Stop rotating if we finished
  35. rotator.GoalRotation = null;
  36. Dirty(uid, rotator);
  37. }
  38. }
  39. }
  40. private void OnRequestRotation(RequestMouseRotatorRotationEvent msg, EntitySessionEventArgs args)
  41. {
  42. if (args.SenderSession.AttachedEntity is not { } ent
  43. || !TryComp<MouseRotatorComponent>(ent, out var rotator))
  44. {
  45. Log.Error($"User {args.SenderSession.Name} ({args.SenderSession.UserId}) tried setting local rotation directly without a valid mouse rotator component attached!");
  46. return;
  47. }
  48. rotator.GoalRotation = msg.Rotation;
  49. Dirty(ent, rotator);
  50. }
  51. }