Fix rotate verbs not being predicted (#38165)
* Fix rotate verbs not being predicted * fixes --------- Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
This commit is contained in:
@@ -1,15 +0,0 @@
|
|||||||
using Robust.Shared.Prototypes;
|
|
||||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
|
||||||
|
|
||||||
namespace Content.Server.Rotatable
|
|
||||||
{
|
|
||||||
[RegisterComponent]
|
|
||||||
public sealed partial class FlippableComponent : Component
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Entity to replace this entity with when the current one is 'flipped'.
|
|
||||||
/// </summary>
|
|
||||||
[DataField("mirrorEntity", required: true, customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
|
|
||||||
public string MirrorEntity = default!;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,197 +0,0 @@
|
|||||||
using Content.Server.Popups;
|
|
||||||
using Content.Shared.ActionBlocker;
|
|
||||||
using Content.Shared.Input;
|
|
||||||
using Content.Shared.Interaction;
|
|
||||||
using Content.Shared.Rotatable;
|
|
||||||
using Content.Shared.Verbs;
|
|
||||||
using Robust.Shared.Input.Binding;
|
|
||||||
using Robust.Shared.Map;
|
|
||||||
using Robust.Shared.Player;
|
|
||||||
using Robust.Shared.Physics;
|
|
||||||
using Robust.Shared.Physics.Components;
|
|
||||||
using Robust.Shared.Utility;
|
|
||||||
|
|
||||||
namespace Content.Server.Rotatable
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Handles verbs for the <see cref="RotatableComponent"/> and <see cref="FlippableComponent"/> components.
|
|
||||||
/// </summary>
|
|
||||||
public sealed class RotatableSystem : EntitySystem
|
|
||||||
{
|
|
||||||
[Dependency] private readonly PopupSystem _popup = default!;
|
|
||||||
[Dependency] private readonly ActionBlockerSystem _actionBlocker = default!;
|
|
||||||
[Dependency] private readonly SharedInteractionSystem _interaction = default!;
|
|
||||||
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
|
||||||
|
|
||||||
public override void Initialize()
|
|
||||||
{
|
|
||||||
SubscribeLocalEvent<FlippableComponent, GetVerbsEvent<Verb>>(AddFlipVerb);
|
|
||||||
SubscribeLocalEvent<RotatableComponent, GetVerbsEvent<Verb>>(AddRotateVerbs);
|
|
||||||
|
|
||||||
CommandBinds.Builder
|
|
||||||
.Bind(ContentKeyFunctions.RotateObjectClockwise, new PointerInputCmdHandler(HandleRotateObjectClockwise))
|
|
||||||
.Bind(ContentKeyFunctions.RotateObjectCounterclockwise, new PointerInputCmdHandler(HandleRotateObjectCounterclockwise))
|
|
||||||
.Bind(ContentKeyFunctions.FlipObject, new PointerInputCmdHandler(HandleFlipObject))
|
|
||||||
.Register<RotatableSystem>();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddFlipVerb(EntityUid uid, FlippableComponent component, GetVerbsEvent<Verb> args)
|
|
||||||
{
|
|
||||||
if (!args.CanAccess
|
|
||||||
|| !args.CanInteract
|
|
||||||
|| !args.CanComplexInteract)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Check if the object is anchored.
|
|
||||||
if (TryComp(uid, out PhysicsComponent? physics) && physics.BodyType == BodyType.Static)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Verb verb = new()
|
|
||||||
{
|
|
||||||
Act = () => Flip(uid, component),
|
|
||||||
Text = Loc.GetString("flippable-verb-get-data-text"),
|
|
||||||
Category = VerbCategory.Rotate,
|
|
||||||
Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/flip.svg.192dpi.png")),
|
|
||||||
Priority = -3, // show flip last
|
|
||||||
DoContactInteraction = true
|
|
||||||
};
|
|
||||||
args.Verbs.Add(verb);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddRotateVerbs(EntityUid uid, RotatableComponent component, GetVerbsEvent<Verb> args)
|
|
||||||
{
|
|
||||||
if (!args.CanAccess
|
|
||||||
|| !args.CanInteract
|
|
||||||
|| !args.CanComplexInteract
|
|
||||||
|| Transform(uid).NoLocalRotation) // Good ol prototype inheritance, eh?
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Check if the object is anchored, and whether we are still allowed to rotate it.
|
|
||||||
if (!component.RotateWhileAnchored &&
|
|
||||||
TryComp(uid, out PhysicsComponent? physics) &&
|
|
||||||
physics.BodyType == BodyType.Static)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Verb resetRotation = new()
|
|
||||||
{
|
|
||||||
DoContactInteraction = true,
|
|
||||||
Act = () => Comp<TransformComponent>(uid).LocalRotation = Angle.Zero,
|
|
||||||
Category = VerbCategory.Rotate,
|
|
||||||
Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/refresh.svg.192dpi.png")),
|
|
||||||
Text = "Reset",
|
|
||||||
Priority = -2, // show CCW, then CW, then reset
|
|
||||||
CloseMenu = false,
|
|
||||||
};
|
|
||||||
args.Verbs.Add(resetRotation);
|
|
||||||
|
|
||||||
// rotate clockwise
|
|
||||||
Verb rotateCW = new()
|
|
||||||
{
|
|
||||||
Act = () => Comp<TransformComponent>(uid).LocalRotation -= component.Increment,
|
|
||||||
Category = VerbCategory.Rotate,
|
|
||||||
Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/rotate_cw.svg.192dpi.png")),
|
|
||||||
Priority = -1,
|
|
||||||
CloseMenu = false, // allow for easy double rotations.
|
|
||||||
};
|
|
||||||
args.Verbs.Add(rotateCW);
|
|
||||||
|
|
||||||
// rotate counter-clockwise
|
|
||||||
Verb rotateCCW = new()
|
|
||||||
{
|
|
||||||
Act = () => Comp<TransformComponent>(uid).LocalRotation += component.Increment,
|
|
||||||
Category = VerbCategory.Rotate,
|
|
||||||
Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/rotate_ccw.svg.192dpi.png")),
|
|
||||||
Priority = 0,
|
|
||||||
CloseMenu = false, // allow for easy double rotations.
|
|
||||||
};
|
|
||||||
args.Verbs.Add(rotateCCW);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Replace a flippable entity with it's flipped / mirror-symmetric entity.
|
|
||||||
/// </summary>
|
|
||||||
public void Flip(EntityUid uid, FlippableComponent component)
|
|
||||||
{
|
|
||||||
var oldTransform = Comp<TransformComponent>(uid);
|
|
||||||
var entity = Spawn(component.MirrorEntity, oldTransform.Coordinates);
|
|
||||||
var newTransform = Comp<TransformComponent>(entity);
|
|
||||||
newTransform.LocalRotation = oldTransform.LocalRotation;
|
|
||||||
_transform.Unanchor(entity, newTransform);
|
|
||||||
Del(uid);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool HandleRotateObjectClockwise(ICommonSession? playerSession, EntityCoordinates coordinates, EntityUid entity)
|
|
||||||
{
|
|
||||||
if (playerSession?.AttachedEntity is not { Valid: true } player || !Exists(player))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!TryComp<RotatableComponent>(entity, out var rotatableComp))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!_actionBlocker.CanInteract(player, entity)
|
|
||||||
|| !_actionBlocker.CanComplexInteract(player)
|
|
||||||
|| !_interaction.InRangeAndAccessible(player, entity))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Check if the object is anchored, and whether we are still allowed to rotate it.
|
|
||||||
if (!rotatableComp.RotateWhileAnchored && TryComp(entity, out PhysicsComponent? physics) &&
|
|
||||||
physics.BodyType == BodyType.Static)
|
|
||||||
{
|
|
||||||
_popup.PopupEntity(Loc.GetString("rotatable-component-try-rotate-stuck"), entity, player);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Transform(entity).LocalRotation -= rotatableComp.Increment;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool HandleRotateObjectCounterclockwise(ICommonSession? playerSession, EntityCoordinates coordinates, EntityUid entity)
|
|
||||||
{
|
|
||||||
if (playerSession?.AttachedEntity is not { Valid: true } player || !Exists(player))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!TryComp<RotatableComponent>(entity, out var rotatableComp))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!_actionBlocker.CanInteract(player, entity)
|
|
||||||
|| !_actionBlocker.CanComplexInteract(player)
|
|
||||||
|| !_interaction.InRangeAndAccessible(player, entity))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Check if the object is anchored, and whether we are still allowed to rotate it.
|
|
||||||
if (!rotatableComp.RotateWhileAnchored && TryComp(entity, out PhysicsComponent? physics) &&
|
|
||||||
physics.BodyType == BodyType.Static)
|
|
||||||
{
|
|
||||||
_popup.PopupEntity(Loc.GetString("rotatable-component-try-rotate-stuck"), entity, player);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Transform(entity).LocalRotation += rotatableComp.Increment;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool HandleFlipObject(ICommonSession? playerSession, EntityCoordinates coordinates, EntityUid entity)
|
|
||||||
{
|
|
||||||
if (playerSession?.AttachedEntity is not { Valid: true } player || !Exists(player))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!TryComp<FlippableComponent>(entity, out var flippableComp))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!_actionBlocker.CanInteract(player, entity)
|
|
||||||
|| !_actionBlocker.CanComplexInteract(player)
|
|
||||||
|| !_interaction.InRangeAndAccessible(player, entity))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Check if the object is anchored.
|
|
||||||
if (TryComp(entity, out PhysicsComponent? physics) && physics.BodyType == BodyType.Static)
|
|
||||||
{
|
|
||||||
_popup.PopupEntity(Loc.GetString("flippable-component-try-flip-is-stuck"), entity, player);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Flip(entity, flippableComp);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
17
Content.Shared/Rotatable/FlippableComponent.cs
Normal file
17
Content.Shared/Rotatable/FlippableComponent.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
using Robust.Shared.GameStates;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
|
namespace Content.Shared.Rotatable;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Allows an entity to be flipped (mirrored) by using a verb.
|
||||||
|
/// </summary>
|
||||||
|
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||||
|
public sealed partial class FlippableComponent : Component
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Entity to replace this entity with when the current one is 'flipped'.
|
||||||
|
/// </summary>
|
||||||
|
[DataField(required: true), AutoNetworkedField]
|
||||||
|
public EntProtoId MirrorEntity = default!;
|
||||||
|
}
|
||||||
@@ -1,27 +1,28 @@
|
|||||||
namespace Content.Shared.Rotatable
|
using Robust.Shared.GameStates;
|
||||||
|
|
||||||
|
namespace Content.Shared.Rotatable;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Allows an entity to be rotated by using a verb.
|
||||||
|
/// </summary>
|
||||||
|
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||||
|
public sealed partial class RotatableComponent : Component
|
||||||
{
|
{
|
||||||
[RegisterComponent]
|
|
||||||
public sealed partial class RotatableComponent : Component
|
|
||||||
{
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// If true, this entity can be rotated even while anchored.
|
/// If true, this entity can be rotated even while anchored.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
[DataField, AutoNetworkedField]
|
||||||
[DataField("rotateWhileAnchored")]
|
public bool RotateWhileAnchored;
|
||||||
public bool RotateWhileAnchored { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// If true, will rotate entity in players direction when pulled
|
/// If true, will rotate entity in players direction when pulled
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
[DataField, AutoNetworkedField]
|
||||||
[DataField("rotateWhilePulling")]
|
public bool RotateWhilePulling = true;
|
||||||
public bool RotateWhilePulling { get; private set; } = true;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The angular value to change when using the rotate verbs.
|
/// The angular value to change when using the rotate verbs.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
[DataField, AutoNetworkedField]
|
||||||
[DataField("increment")]
|
public Angle Increment = Angle.FromDegrees(90);
|
||||||
public Angle Increment { get; private set; } = Angle.FromDegrees(90);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
213
Content.Shared/Rotatable/RotatableSystem.cs
Normal file
213
Content.Shared/Rotatable/RotatableSystem.cs
Normal file
@@ -0,0 +1,213 @@
|
|||||||
|
using Content.Shared.ActionBlocker;
|
||||||
|
using Content.Shared.Input;
|
||||||
|
using Content.Shared.Interaction;
|
||||||
|
using Content.Shared.Popups;
|
||||||
|
using Content.Shared.Verbs;
|
||||||
|
using Robust.Shared.Input.Binding;
|
||||||
|
using Robust.Shared.Map;
|
||||||
|
using Robust.Shared.Physics;
|
||||||
|
using Robust.Shared.Physics.Components;
|
||||||
|
using Robust.Shared.Player;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
|
namespace Content.Shared.Rotatable;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handles verbs for the <see cref="RotatableComponent"/> and <see cref="FlippableComponent"/> components.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class RotatableSystem : EntitySystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly ActionBlockerSystem _actionBlocker = default!;
|
||||||
|
[Dependency] private readonly SharedInteractionSystem _interaction = default!;
|
||||||
|
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||||
|
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
SubscribeLocalEvent<FlippableComponent, GetVerbsEvent<Verb>>(AddFlipVerb);
|
||||||
|
SubscribeLocalEvent<RotatableComponent, GetVerbsEvent<Verb>>(AddRotateVerbs);
|
||||||
|
|
||||||
|
CommandBinds.Builder
|
||||||
|
.Bind(ContentKeyFunctions.RotateObjectClockwise, new PointerInputCmdHandler(HandleRotateObjectClockwise))
|
||||||
|
.Bind(ContentKeyFunctions.RotateObjectCounterclockwise, new PointerInputCmdHandler(HandleRotateObjectCounterclockwise))
|
||||||
|
.Bind(ContentKeyFunctions.FlipObject, new PointerInputCmdHandler(HandleFlipObject))
|
||||||
|
.Register<RotatableSystem>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddFlipVerb(EntityUid uid, FlippableComponent component, GetVerbsEvent<Verb> args)
|
||||||
|
{
|
||||||
|
if (!args.CanAccess
|
||||||
|
|| !args.CanInteract
|
||||||
|
|| !args.CanComplexInteract)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Check if the object is anchored.
|
||||||
|
if (TryComp<PhysicsComponent>(uid, out var physics) && physics.BodyType == BodyType.Static)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Verb verb = new()
|
||||||
|
{
|
||||||
|
Act = () => Flip(uid, component),
|
||||||
|
Text = Loc.GetString("flippable-verb-get-data-text"),
|
||||||
|
Category = VerbCategory.Rotate,
|
||||||
|
Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/flip.svg.192dpi.png")),
|
||||||
|
Priority = -3, // show flip last
|
||||||
|
DoContactInteraction = true
|
||||||
|
};
|
||||||
|
args.Verbs.Add(verb);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddRotateVerbs(EntityUid uid, RotatableComponent component, GetVerbsEvent<Verb> args)
|
||||||
|
{
|
||||||
|
if (!args.CanAccess
|
||||||
|
|| !args.CanInteract
|
||||||
|
|| !args.CanComplexInteract
|
||||||
|
|| Transform(uid).NoLocalRotation) // Good ol prototype inheritance, eh?
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Check if the object is anchored, and whether we are still allowed to rotate it.
|
||||||
|
if (!component.RotateWhileAnchored &&
|
||||||
|
TryComp<PhysicsComponent>(uid, out var physics) &&
|
||||||
|
physics.BodyType == BodyType.Static)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Verb resetRotation = new()
|
||||||
|
{
|
||||||
|
DoContactInteraction = true,
|
||||||
|
Act = () => ResetRotation(uid),
|
||||||
|
Category = VerbCategory.Rotate,
|
||||||
|
Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/refresh.svg.192dpi.png")),
|
||||||
|
Text = Loc.GetString("rotate-reset-verb-get-data-text"),
|
||||||
|
Priority = -2, // show CCW, then CW, then reset
|
||||||
|
CloseMenu = false,
|
||||||
|
};
|
||||||
|
args.Verbs.Add(resetRotation);
|
||||||
|
|
||||||
|
// rotate clockwise
|
||||||
|
Verb rotateCW = new()
|
||||||
|
{
|
||||||
|
Act = () => Rotate(uid, -component.Increment),
|
||||||
|
Category = VerbCategory.Rotate,
|
||||||
|
Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/rotate_cw.svg.192dpi.png")),
|
||||||
|
Text = Loc.GetString("rotate-verb-get-data-text"),
|
||||||
|
Priority = -1,
|
||||||
|
CloseMenu = false, // allow for easy double rotations.
|
||||||
|
};
|
||||||
|
args.Verbs.Add(rotateCW);
|
||||||
|
|
||||||
|
// rotate counter-clockwise
|
||||||
|
Verb rotateCCW = new()
|
||||||
|
{
|
||||||
|
Act = () => Rotate(uid, component.Increment),
|
||||||
|
Category = VerbCategory.Rotate,
|
||||||
|
Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/rotate_ccw.svg.192dpi.png")),
|
||||||
|
Text = Loc.GetString("rotate-counter-verb-get-data-text"),
|
||||||
|
Priority = 0,
|
||||||
|
CloseMenu = false, // allow for easy double rotations.
|
||||||
|
};
|
||||||
|
args.Verbs.Add(rotateCCW);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Replace a flippable entity with it's flipped / mirror-symmetric entity.
|
||||||
|
/// </summary>
|
||||||
|
public void Flip(EntityUid uid, FlippableComponent component)
|
||||||
|
{
|
||||||
|
var oldTransform = Comp<TransformComponent>(uid);
|
||||||
|
var entity = PredictedSpawnAtPosition(component.MirrorEntity, oldTransform.Coordinates);
|
||||||
|
var newTransform = Comp<TransformComponent>(entity);
|
||||||
|
_transform.SetLocalRotation(entity, oldTransform.LocalRotation);
|
||||||
|
_transform.Unanchor(entity, newTransform);
|
||||||
|
PredictedDel(uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool HandleRotateObjectClockwise(ICommonSession? playerSession, EntityCoordinates coordinates, EntityUid entity)
|
||||||
|
{
|
||||||
|
if (playerSession?.AttachedEntity is not { Valid: true } player || !Exists(player))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!TryComp<RotatableComponent>(entity, out var rotatableComp))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!_actionBlocker.CanInteract(player, entity)
|
||||||
|
|| !_actionBlocker.CanComplexInteract(player)
|
||||||
|
|| !_interaction.InRangeAndAccessible(player, entity))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Check if the object is anchored, and whether we are still allowed to rotate it.
|
||||||
|
if (!rotatableComp.RotateWhileAnchored && TryComp<PhysicsComponent>(entity, out var physics) &&
|
||||||
|
physics.BodyType == BodyType.Static)
|
||||||
|
{
|
||||||
|
_popup.PopupClient(Loc.GetString("rotatable-component-try-rotate-stuck"), entity, player);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Rotate(entity, -rotatableComp.Increment);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool HandleRotateObjectCounterclockwise(ICommonSession? playerSession, EntityCoordinates coordinates, EntityUid entity)
|
||||||
|
{
|
||||||
|
if (playerSession?.AttachedEntity is not { Valid: true } player || !Exists(player))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!TryComp<RotatableComponent>(entity, out var rotatableComp))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!_actionBlocker.CanInteract(player, entity)
|
||||||
|
|| !_actionBlocker.CanComplexInteract(player)
|
||||||
|
|| !_interaction.InRangeAndAccessible(player, entity))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Check if the object is anchored, and whether we are still allowed to rotate it.
|
||||||
|
if (!rotatableComp.RotateWhileAnchored && TryComp<PhysicsComponent>(entity, out var physics) &&
|
||||||
|
physics.BodyType == BodyType.Static)
|
||||||
|
{
|
||||||
|
_popup.PopupClient(Loc.GetString("rotatable-component-try-rotate-stuck"), entity, player);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Rotate(entity, rotatableComp.Increment);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool HandleFlipObject(ICommonSession? playerSession, EntityCoordinates coordinates, EntityUid entity)
|
||||||
|
{
|
||||||
|
if (playerSession?.AttachedEntity is not { Valid: true } player || !Exists(player))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!TryComp<FlippableComponent>(entity, out var flippableComp))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!_actionBlocker.CanInteract(player, entity)
|
||||||
|
|| !_actionBlocker.CanComplexInteract(player)
|
||||||
|
|| !_interaction.InRangeAndAccessible(player, entity))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Check if the object is anchored.
|
||||||
|
if (TryComp<PhysicsComponent>(entity, out var physics) && physics.BodyType == BodyType.Static)
|
||||||
|
{
|
||||||
|
_popup.PopupClient(Loc.GetString("flippable-component-try-flip-is-stuck"), entity, player);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Flip(entity, flippableComp);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Rotate(Entity<TransformComponent?> ent, Angle angle)
|
||||||
|
{
|
||||||
|
if (!Resolve(ent, ref ent.Comp, false))
|
||||||
|
return;
|
||||||
|
|
||||||
|
_transform.SetLocalRotation(ent.Owner, ent.Comp.LocalRotation + angle);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ResetRotation(Entity<TransformComponent?> ent)
|
||||||
|
{
|
||||||
|
if (!Resolve(ent, ref ent.Comp, false))
|
||||||
|
return;
|
||||||
|
|
||||||
|
_transform.SetLocalRotation(ent.Owner, Angle.Zero);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,3 +6,6 @@ rotate-verb-get-data-text = Rotate clockwise
|
|||||||
|
|
||||||
# RotateCounterVerb
|
# RotateCounterVerb
|
||||||
rotate-counter-verb-get-data-text = Rotate counter-clockwise
|
rotate-counter-verb-get-data-text = Rotate counter-clockwise
|
||||||
|
|
||||||
|
# ResetVerb
|
||||||
|
rotate-reset-verb-get-data-text = Reset
|
||||||
|
|||||||
Reference in New Issue
Block a user