From c7f104cd9364e78a408cf87105b342339969353d Mon Sep 17 00:00:00 2001 From: 20kdc Date: Thu, 27 May 2021 11:51:14 +0100 Subject: [PATCH] More rotatability (#4067) * Make barstools, PA components, and radiation collectors rotatable. Making barstools rotatable is so that people can spin on the barstool. (RP moment.) The other two are more "functional" changes for assembling a PA. * Allow rotating a rotate-while-anchored object if you're buckled to it. Barstool spinny * Fix bug with rotation of an object that someone is buckled to * BuckleSystem: Efficiency improvements with directed events * Don't need to unsubscribe anymore from events, so in BuckleSystem, just don't --- .../Components/Buckle/BuckleComponent.cs | 2 +- .../GameObjects/EntitySystems/BuckleSystem.cs | 70 +++++++++---------- .../EntitySystems/Click/InteractionSystem.cs | 23 +++++- .../Constructible/Furniture/seats.yml | 2 + .../Constructible/Power/Engines/PA/base.yml | 1 + .../Power/Engines/Singularity/collector.yml | 1 + 6 files changed, 60 insertions(+), 39 deletions(-) diff --git a/Content.Client/GameObjects/Components/Buckle/BuckleComponent.cs b/Content.Client/GameObjects/Components/Buckle/BuckleComponent.cs index 3584810116..e8d5cc9877 100644 --- a/Content.Client/GameObjects/Components/Buckle/BuckleComponent.cs +++ b/Content.Client/GameObjects/Components/Buckle/BuckleComponent.cs @@ -43,7 +43,7 @@ namespace Content.Client.GameObjects.Components.Buckle return; } - if (!_buckled && _originalDrawDepth.HasValue) + if (_originalDrawDepth.HasValue && !buckle.DrawDepth.HasValue) { ownerSprite.DrawDepth = _originalDrawDepth.Value; _originalDrawDepth = null; diff --git a/Content.Server/GameObjects/EntitySystems/BuckleSystem.cs b/Content.Server/GameObjects/EntitySystems/BuckleSystem.cs index 066dafe27d..fe728426cd 100644 --- a/Content.Server/GameObjects/EntitySystems/BuckleSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/BuckleSystem.cs @@ -20,24 +20,19 @@ namespace Content.Server.GameObjects.EntitySystems UpdatesAfter.Add(typeof(InteractionSystem)); UpdatesAfter.Add(typeof(InputSystem)); - SubscribeLocalEvent(MoveEvent); - SubscribeLocalEvent(ContainerModified); - SubscribeLocalEvent(ContainerModified); + SubscribeLocalEvent(MoveEvent); + + SubscribeLocalEvent(RotateEvent); + + SubscribeLocalEvent(ContainerModifiedBuckle); + SubscribeLocalEvent(ContainerModifiedStrap); + + SubscribeLocalEvent(ContainerModifiedBuckle); + SubscribeLocalEvent(ContainerModifiedStrap); SubscribeLocalEvent(HandleAttackHand); } - public override void Shutdown() - { - base.Shutdown(); - - UnsubscribeLocalEvent(); - UnsubscribeLocalEvent(); - UnsubscribeLocalEvent(); - - UnsubscribeLocalEvent(HandleAttackHand); - } - private void HandleAttackHand(EntityUid uid, BuckleComponent component, AttackHandEvent args) { args.Handled = component.TryUnbuckle(args.User); @@ -51,13 +46,8 @@ namespace Content.Server.GameObjects.EntitySystems } } - private void MoveEvent(MoveEvent ev) + private void MoveEvent(EntityUid uid, BuckleComponent buckle, MoveEvent ev) { - if (!ev.Sender.TryGetComponent(out BuckleComponent? buckle)) - { - return; - } - var strap = buckle.BuckledTo; if (strap == null) @@ -75,25 +65,35 @@ namespace Content.Server.GameObjects.EntitySystems buckle.TryUnbuckle(buckle.Owner, true); } - private void ContainerModified(ContainerModifiedMessage message) + private void RotateEvent(EntityUid uid, StrapComponent strap, RotateEvent ev) { - // Not returning is necessary in case an entity has both a buckle and strap component - if (message.Entity.TryGetComponent(out BuckleComponent? buckle)) + // On rotation of a strap, reattach all buckled entities. + // This fixes buckle offsets and draw depths. + foreach (var buckledEntity in strap.BuckledEntities) { - ContainerModifiedReAttach(buckle, buckle.BuckledTo); - } - - if (message.Entity.TryGetComponent(out StrapComponent? strap)) - { - foreach (var buckledEntity in strap.BuckledEntities) + if (!buckledEntity.TryGetComponent(out BuckleComponent? buckled)) { - if (!buckledEntity.TryGetComponent(out BuckleComponent? buckled)) - { - continue; - } - - ContainerModifiedReAttach(buckled, strap); + continue; } + buckled.ReAttach(strap); + buckled.Dirty(); + } + } + + private void ContainerModifiedBuckle(EntityUid uid, BuckleComponent buckle, ContainerModifiedMessage message) + { + ContainerModifiedReAttach(buckle, buckle.BuckledTo); + } + private void ContainerModifiedStrap(EntityUid uid, StrapComponent strap, ContainerModifiedMessage message) + { + foreach (var buckledEntity in strap.BuckledEntities) + { + if (!buckledEntity.TryGetComponent(out BuckleComponent? buckled)) + { + continue; + } + + ContainerModifiedReAttach(buckled, strap); } } diff --git a/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs b/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs index fd7881d4bf..2c3ba58163 100644 --- a/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs @@ -4,10 +4,12 @@ using System.Threading.Tasks; using Content.Server.GameObjects.Components.Items.Storage; using Content.Server.GameObjects.Components.Mobs; using Content.Server.GameObjects.Components.Pulling; +using Content.Server.GameObjects.Components.Buckle; using Content.Server.GameObjects.Components.Timing; using Content.Server.Interfaces.GameObjects.Components.Items; using Content.Shared.GameObjects.Components.Inventory; using Content.Shared.GameObjects.Components.Items; +using Content.Shared.GameObjects.Components.Rotatable; using Content.Shared.GameObjects.EntitySystemMessages; using Content.Shared.GameObjects.EntitySystems; using Content.Shared.GameObjects.EntitySystems.ActionBlocker; @@ -389,12 +391,27 @@ namespace Content.Server.GameObjects.EntitySystems.Click private void ClickFace(IEntity player, EntityCoordinates coordinates) { + var diff = coordinates.ToMapPos(EntityManager) - player.Transform.MapPosition.Position; + if (diff.LengthSquared <= 0.01f) + return; + var diffAngle = Angle.FromWorldVec(diff); if (ActionBlockerSystem.CanChangeDirection(player)) { - var diff = coordinates.ToMapPos(EntityManager) - player.Transform.MapPosition.Position; - if (diff.LengthSquared > 0.01f) + player.Transform.LocalRotation = diffAngle; + } + else + { + if (player.TryGetComponent(out BuckleComponent? buckle) && (buckle.BuckledTo != null)) { - player.Transform.LocalRotation = Angle.FromWorldVec(diff); + // We're buckled to another object. Is that object rotatable? + if (buckle.BuckledTo!.Owner.TryGetComponent(out SharedRotatableComponent? rotatable) && rotatable.RotateWhileAnchored) + { + // Note the assumption that even if unanchored, player can only do spinnychair with an "independent wheel". + // (Since the player being buckled to it holds it down with their weight.) + // This is logically equivalent to RotateWhileAnchored. + // Barstools and office chairs have independent wheels, while regular chairs don't. + rotatable.Owner.Transform.LocalRotation = diffAngle; + } } } } diff --git a/Resources/Prototypes/Entities/Constructible/Furniture/seats.yml b/Resources/Prototypes/Entities/Constructible/Furniture/seats.yml index d3c53a1716..617447f05f 100644 --- a/Resources/Prototypes/Entities/Constructible/Furniture/seats.yml +++ b/Resources/Prototypes/Entities/Constructible/Furniture/seats.yml @@ -89,6 +89,8 @@ id: StoolBar parent: SeatBase components: + - type: Rotatable + rotateWhileAnchored: true - type: Anchorable - type: Sprite state: bar_stool diff --git a/Resources/Prototypes/Entities/Constructible/Power/Engines/PA/base.yml b/Resources/Prototypes/Entities/Constructible/Power/Engines/PA/base.yml index fa139ca653..61b1e756d1 100644 --- a/Resources/Prototypes/Entities/Constructible/Power/Engines/PA/base.yml +++ b/Resources/Prototypes/Entities/Constructible/Power/Engines/PA/base.yml @@ -6,6 +6,7 @@ components: - type: InteractionOutline - type: Anchorable + - type: Rotatable - type: Physics bodyType: Static fixtures: diff --git a/Resources/Prototypes/Entities/Constructible/Power/Engines/Singularity/collector.yml b/Resources/Prototypes/Entities/Constructible/Power/Engines/Singularity/collector.yml index c1f99b06d9..44ada0eed7 100644 --- a/Resources/Prototypes/Entities/Constructible/Power/Engines/Singularity/collector.yml +++ b/Resources/Prototypes/Entities/Constructible/Power/Engines/Singularity/collector.yml @@ -40,4 +40,5 @@ nodeGroupID: HVPower - type: RadiationCollector - type: Anchorable + - type: Rotatable - type: Pullable