2023-09-22 22:45:13 -07:00
using Content.Shared.Interaction ;
using Robust.Shared.Timing ;
namespace Content.Shared.MouseRotator ;
/// <summary>
/// This handles rotating an entity based on mouse location
/// </summary>
/// <see cref="MouseRotatorComponent"/>
public abstract class SharedMouseRotatorSystem : EntitySystem
{
[Dependency] private readonly RotateToFaceSystem _rotate = default ! ;
public override void Initialize ( )
{
base . Initialize ( ) ;
SubscribeAllEvent < RequestMouseRotatorRotationEvent > ( OnRequestRotation ) ;
2023-09-24 14:22:44 -07:00
SubscribeAllEvent < RequestMouseRotatorRotationSimpleEvent > ( OnRequestSimpleRotation ) ;
2023-09-22 22:45:13 -07:00
}
public override void Update ( float frameTime )
{
base . Update ( frameTime ) ;
// TODO maybe `ActiveMouseRotatorComponent` to avoid querying over more entities than we need?
// (if this is added to players)
// (but arch makes these fast anyway, so)
var query = EntityQueryEnumerator < MouseRotatorComponent , TransformComponent > ( ) ;
while ( query . MoveNext ( out var uid , out var rotator , out var xform ) )
{
if ( rotator . GoalRotation = = null )
continue ;
if ( _rotate . TryRotateTo (
uid ,
rotator . GoalRotation . Value ,
frameTime ,
rotator . AngleTolerance ,
MathHelper . DegreesToRadians ( rotator . RotationSpeed ) ,
xform ) )
{
// Stop rotating if we finished
rotator . GoalRotation = null ;
2023-09-23 16:39:07 +10:00
Dirty ( uid , rotator ) ;
2023-09-22 22:45:13 -07:00
}
}
}
private void OnRequestRotation ( RequestMouseRotatorRotationEvent msg , EntitySessionEventArgs args )
{
2023-09-24 14:22:44 -07:00
if ( args . SenderSession . AttachedEntity is not { } ent
| | ! TryComp < MouseRotatorComponent > ( ent , out var rotator ) | | rotator . Simple4DirMode )
2023-09-22 22:45:13 -07:00
{
2023-09-24 14:22:44 -07:00
Log . Error ( $"User {args.SenderSession.Name} ({args.SenderSession.UserId}) tried setting local rotation directly without a valid mouse rotator component attached!" ) ;
2023-09-22 22:45:13 -07:00
return ;
}
rotator . GoalRotation = msg . Rotation ;
Dirty ( ent , rotator ) ;
}
2023-09-24 14:22:44 -07:00
private void OnRequestSimpleRotation ( RequestMouseRotatorRotationSimpleEvent ev , EntitySessionEventArgs args )
{
if ( args . SenderSession . AttachedEntity is not { } ent
| | ! TryComp < MouseRotatorComponent > ( ent , out var rotator ) | | ! rotator . Simple4DirMode )
{
2024-01-31 20:13:35 +06:00
Log . Warning ( $"User {args.SenderSession.Name} ({args.SenderSession.UserId}) tried setting 4-dir rotation directly without a valid mouse rotator component attached!" ) ;
2023-09-24 14:22:44 -07:00
return ;
}
rotator . GoalRotation = ev . Direction . ToAngle ( ) ;
Dirty ( ent , rotator ) ;
}
2023-09-22 22:45:13 -07:00
}