| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- 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!;
- 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)
- return;
- // Check if the object is anchored.
- if (EntityManager.TryGetComponent(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
- || 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 &&
- EntityManager.TryGetComponent(uid, out PhysicsComponent? physics) &&
- physics.BodyType == BodyType.Static)
- return;
- Verb resetRotation = new()
- {
- DoContactInteraction = true,
- Act = () => EntityManager.GetComponent<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 = () => EntityManager.GetComponent<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 = () => EntityManager.GetComponent<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 = EntityManager.GetComponent<TransformComponent>(uid);
- var entity = EntityManager.SpawnEntity(component.MirrorEntity, oldTransform.Coordinates);
- var newTransform = EntityManager.GetComponent<TransformComponent>(entity);
- newTransform.LocalRotation = oldTransform.LocalRotation;
- newTransform.Anchored = false;
- EntityManager.DeleteEntity(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) || !_interaction.InRangeAndAccessible(player, entity))
- return false;
- // Check if the object is anchored, and whether we are still allowed to rotate it.
- if (!rotatableComp.RotateWhileAnchored && EntityManager.TryGetComponent(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) || !_interaction.InRangeAndAccessible(player, entity))
- return false;
- // Check if the object is anchored, and whether we are still allowed to rotate it.
- if (!rotatableComp.RotateWhileAnchored && EntityManager.TryGetComponent(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) || !_interaction.InRangeAndAccessible(player, entity))
- return false;
- // Check if the object is anchored.
- if (EntityManager.TryGetComponent(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;
- }
- }
- }
|