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:
@@ -0,0 +1,12 @@
|
||||
#nullable enable
|
||||
using Content.Shared.GameObjects.Components.Rotatable;
|
||||
using Robust.Shared.GameObjects;
|
||||
|
||||
namespace Content.Client.GameObjects.Components.Rotatable
|
||||
{
|
||||
[RegisterComponent]
|
||||
[ComponentReference(typeof(SharedRotatableComponent))]
|
||||
public class RotatableComponent : SharedRotatableComponent
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -56,7 +56,6 @@ namespace Content.Client
|
||||
"Drink",
|
||||
"Food",
|
||||
"FoodContainer",
|
||||
"Rotatable",
|
||||
"MagicMirror",
|
||||
"FloorTile",
|
||||
"ShuttleController",
|
||||
|
||||
@@ -1,27 +1,19 @@
|
||||
using Content.Shared.GameObjects.EntitySystems.ActionBlocker;
|
||||
#nullable enable
|
||||
using Content.Shared.GameObjects.Components.Rotatable;
|
||||
using Content.Shared.GameObjects.EntitySystems.ActionBlocker;
|
||||
using Content.Shared.GameObjects.Verbs;
|
||||
using Content.Shared.Interfaces;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Physics;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Content.Server.GameObjects.Components.Rotatable
|
||||
{
|
||||
[RegisterComponent]
|
||||
public class RotatableComponent : Component
|
||||
[ComponentReference(typeof(SharedRotatableComponent))]
|
||||
public class RotatableComponent : SharedRotatableComponent
|
||||
{
|
||||
public override string Name => "Rotatable";
|
||||
|
||||
/// <summary>
|
||||
/// If true, this entity can be rotated even while anchored.
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField("rotateWhileAnchored")]
|
||||
public bool RotateWhileAnchored { get; private set; }
|
||||
|
||||
private void TryRotate(IEntity user, Angle angle)
|
||||
{
|
||||
if (!RotateWhileAnchored && Owner.TryGetComponent(out IPhysBody? physics))
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
#nullable enable
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Content.Shared.GameObjects.Components.Rotatable
|
||||
{
|
||||
public abstract class SharedRotatableComponent : Component
|
||||
{
|
||||
public override string Name => "Rotatable";
|
||||
|
||||
/// <summary>
|
||||
/// If true, this entity can be rotated even while anchored.
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField("rotateWhileAnchored")]
|
||||
public bool RotateWhileAnchored { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// If true, will rotate entity in players direction when pulled
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField("rotateWhilePulling")]
|
||||
public bool RotateWhilePulling { get; protected set; } = true;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user