Pulling change entity rotation (#3890)

* Moved rotatable to shared

* Pullable change rotation

* Applied review

* Update Content.Shared/GameObjects/EntitySystems/SharedPullingSystem.cs

Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
This commit is contained in:
Alex Evgrashin
2021-05-05 06:29:26 +03:00
committed by GitHub
parent ad3b7fe97d
commit 9857f8197c
5 changed files with 84 additions and 14 deletions

View File

@@ -1,7 +1,9 @@
#nullable enable
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Content.Shared.GameObjects.Components.Pulling;
using Content.Shared.GameObjects.Components.Rotatable;
using Content.Shared.GameObjects.EntitySystemMessages.Pulling;
using Content.Shared.GameTicking;
using Content.Shared.Input;
@@ -11,6 +13,7 @@ using Robust.Shared.Containers;
using Robust.Shared.GameObjects;
using Robust.Shared.Input.Binding;
using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Dynamics.Joints;
using Robust.Shared.Players;
@@ -29,6 +32,20 @@ namespace Content.Shared.GameObjects.EntitySystems
private readonly HashSet<SharedPullableComponent> _moving = new();
private readonly HashSet<SharedPullableComponent> _stoppedMoving = new();
/// <summary>
/// If distance between puller and pulled entity lower that this threshold,
/// pulled entity will not change its rotation.
/// Helps with small distance jittering
/// </summary>
private const float ThresholdRotDistance = 1;
/// <summary>
/// If difference between puller and pulled angle lower that this threshold,
/// pulled entity will not change its rotation.
/// Helps with diagonal movement jittering
/// </summary>
private const float ThresholdRotAngle = 30;
public IReadOnlySet<SharedPullableComponent> Moving => _moving;
public override void Initialize()
@@ -89,6 +106,7 @@ namespace Content.Shared.GameObjects.EntitySystems
private void PullerMoved(MoveEvent ev)
{
var puller = ev.Sender;
if (!TryGetPulled(ev.Sender, out var pulled))
{
return;
@@ -99,6 +117,8 @@ namespace Content.Shared.GameObjects.EntitySystems
return;
}
UpdatePulledRotation(puller, pulled);
physics.WakeBody();
if (pulled.TryGetComponent(out SharedPullableComponent? pullable))
@@ -198,5 +218,26 @@ namespace Content.Shared.GameObjects.EntitySystems
{
return _pullers.ContainsKey(puller);
}
private void UpdatePulledRotation(IEntity puller, IEntity pulled)
{
// TODO: update once ComponentReference works with directed event bus.
if (!pulled.TryGetComponent(out SharedRotatableComponent? rotatable))
return;
if (!rotatable.RotateWhilePulling)
return;
var dir = puller.Transform.WorldPosition - pulled.Transform.WorldPosition;
if (dir.LengthSquared > ThresholdRotDistance * ThresholdRotDistance)
{
var oldAngle = pulled.Transform.WorldRotation;
var newAngle = Angle.FromWorldVec(dir);
var diff = newAngle - oldAngle;
if (Math.Abs(diff.Degrees) > ThresholdRotAngle)
pulled.Transform.WorldRotation = newAngle;
}
}
}
}