using Content.Server.Popups; using Content.Shared.Popups; using Content.Shared.Rotatable; using Content.Shared.Verbs; using Robust.Shared.Physics; using Robust.Shared.Physics.Components; using Robust.Shared.Utility; namespace Content.Server.Rotatable { /// /// Handles verbs for the and components. /// public sealed class RotatableSystem : EntitySystem { [Dependency] private readonly PopupSystem _popup = default!; public override void Initialize() { SubscribeLocalEvent>(AddFlipVerb); SubscribeLocalEvent>(AddRotateVerbs); } private void AddFlipVerb(EntityUid uid, FlippableComponent component, GetVerbsEvent args) { if (!args.CanAccess || !args.CanInteract) return; Verb verb = new() { Act = () => TryFlip(uid, component, args.User), 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 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(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(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(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); } /// /// Replace a flippable entity with it's flipped / mirror-symmetric entity. /// public void TryFlip(EntityUid uid, FlippableComponent component, EntityUid user) { if (EntityManager.TryGetComponent(uid, out PhysicsComponent? physics) && physics.BodyType == BodyType.Static) { _popup.PopupEntity(Loc.GetString("flippable-component-try-flip-is-stuck"), uid, user); return; } var oldTransform = EntityManager.GetComponent(uid); var entity = EntityManager.SpawnEntity(component.MirrorEntity, oldTransform.Coordinates); var newTransform = EntityManager.GetComponent(entity); newTransform.LocalRotation = oldTransform.LocalRotation; newTransform.Anchored = false; EntityManager.DeleteEntity(uid); } } }