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