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

@@ -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
{
}
}

View File

@@ -56,7 +56,6 @@ namespace Content.Client
"Drink", "Drink",
"Food", "Food",
"FoodContainer", "FoodContainer",
"Rotatable",
"MagicMirror", "MagicMirror",
"FloorTile", "FloorTile",
"ShuttleController", "ShuttleController",

View File

@@ -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.GameObjects.Verbs;
using Content.Shared.Interfaces; using Content.Shared.Interfaces;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
using Robust.Shared.Localization; using Robust.Shared.Localization;
using Robust.Shared.Maths; using Robust.Shared.Maths;
using Robust.Shared.Physics; using Robust.Shared.Physics;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.ViewVariables;
namespace Content.Server.GameObjects.Components.Rotatable namespace Content.Server.GameObjects.Components.Rotatable
{ {
[RegisterComponent] [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) private void TryRotate(IEntity user, Angle angle)
{ {
if (!RotateWhileAnchored && Owner.TryGetComponent(out IPhysBody? physics)) if (!RotateWhileAnchored && Owner.TryGetComponent(out IPhysBody? physics))

View File

@@ -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;
}
}

View File

@@ -1,7 +1,9 @@
#nullable enable #nullable enable
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using Content.Shared.GameObjects.Components.Pulling; using Content.Shared.GameObjects.Components.Pulling;
using Content.Shared.GameObjects.Components.Rotatable;
using Content.Shared.GameObjects.EntitySystemMessages.Pulling; using Content.Shared.GameObjects.EntitySystemMessages.Pulling;
using Content.Shared.GameTicking; using Content.Shared.GameTicking;
using Content.Shared.Input; using Content.Shared.Input;
@@ -11,6 +13,7 @@ using Robust.Shared.Containers;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
using Robust.Shared.Input.Binding; using Robust.Shared.Input.Binding;
using Robust.Shared.Map; using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Physics; using Robust.Shared.Physics;
using Robust.Shared.Physics.Dynamics.Joints; using Robust.Shared.Physics.Dynamics.Joints;
using Robust.Shared.Players; using Robust.Shared.Players;
@@ -29,6 +32,20 @@ namespace Content.Shared.GameObjects.EntitySystems
private readonly HashSet<SharedPullableComponent> _moving = new(); private readonly HashSet<SharedPullableComponent> _moving = new();
private readonly HashSet<SharedPullableComponent> _stoppedMoving = 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 IReadOnlySet<SharedPullableComponent> Moving => _moving;
public override void Initialize() public override void Initialize()
@@ -89,6 +106,7 @@ namespace Content.Shared.GameObjects.EntitySystems
private void PullerMoved(MoveEvent ev) private void PullerMoved(MoveEvent ev)
{ {
var puller = ev.Sender;
if (!TryGetPulled(ev.Sender, out var pulled)) if (!TryGetPulled(ev.Sender, out var pulled))
{ {
return; return;
@@ -99,6 +117,8 @@ namespace Content.Shared.GameObjects.EntitySystems
return; return;
} }
UpdatePulledRotation(puller, pulled);
physics.WakeBody(); physics.WakeBody();
if (pulled.TryGetComponent(out SharedPullableComponent? pullable)) if (pulled.TryGetComponent(out SharedPullableComponent? pullable))
@@ -198,5 +218,26 @@ namespace Content.Shared.GameObjects.EntitySystems
{ {
return _pullers.ContainsKey(puller); 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;
}
}
} }
} }