diff --git a/Content.Client/GameObjects/Components/Mobs/BuckleComponent.cs b/Content.Client/GameObjects/Components/Buckle/BuckleComponent.cs similarity index 90% rename from Content.Client/GameObjects/Components/Mobs/BuckleComponent.cs rename to Content.Client/GameObjects/Components/Buckle/BuckleComponent.cs index f793567e57..77f0b099b4 100644 --- a/Content.Client/GameObjects/Components/Mobs/BuckleComponent.cs +++ b/Content.Client/GameObjects/Components/Buckle/BuckleComponent.cs @@ -1,10 +1,10 @@ using Content.Client.GameObjects.Components.Strap; using Content.Client.Interfaces.GameObjects.Components.Interaction; -using Content.Shared.GameObjects.Components.Mobs; +using Content.Shared.GameObjects.Components.Buckle; using Robust.Client.GameObjects; using Robust.Shared.GameObjects; -namespace Content.Client.GameObjects.Components.Mobs +namespace Content.Client.GameObjects.Components.Buckle { [RegisterComponent] public class BuckleComponent : SharedBuckleComponent, IClientDraggable @@ -12,7 +12,7 @@ namespace Content.Client.GameObjects.Components.Mobs private bool _buckled; private int? _originalDrawDepth; - protected override bool Buckled => _buckled; + public override bool Buckled => _buckled; public override void HandleComponentState(ComponentState curState, ComponentState nextState) { diff --git a/Content.Client/GameObjects/Components/Buckle/BuckleVisualizer.cs b/Content.Client/GameObjects/Components/Buckle/BuckleVisualizer.cs new file mode 100644 index 0000000000..d460843dac --- /dev/null +++ b/Content.Client/GameObjects/Components/Buckle/BuckleVisualizer.cs @@ -0,0 +1,68 @@ +using System; +using Content.Shared.GameObjects.Components.Buckle; +using Content.Shared.GameObjects.Components.Strap; +using JetBrains.Annotations; +using Robust.Client.Animations; +using Robust.Client.GameObjects; +using Robust.Client.GameObjects.Components.Animations; +using Robust.Client.Interfaces.GameObjects.Components; +using Robust.Shared.Animations; +using Robust.Shared.Maths; + +namespace Content.Client.GameObjects.Components.Buckle +{ + [UsedImplicitly] + public class BuckleVisualizer : AppearanceVisualizer + { + public override void OnChangeData(AppearanceComponent component) + { + if (!component.TryGetData(BuckleVisuals.Buckled, out var buckled) || + !buckled) + { + return; + } + + if (!component.TryGetData(StrapVisuals.RotationAngle, out var angle)) + { + return; + } + + SetRotation(component, Angle.FromDegrees(angle)); + } + + private void SetRotation(AppearanceComponent component, Angle rotation) + { + var sprite = component.Owner.GetComponent(); + + if (!sprite.Owner.TryGetComponent(out AnimationPlayerComponent animation)) + { + sprite.Rotation = rotation; + return; + } + + if (animation.HasRunningAnimation("rotate")) + { + animation.Stop("rotate"); + } + + animation.Play(new Animation + { + Length = TimeSpan.FromSeconds(0.125), + AnimationTracks = + { + new AnimationTrackComponentProperty + { + ComponentType = typeof(ISpriteComponent), + Property = nameof(ISpriteComponent.Rotation), + InterpolationMode = AnimationInterpolationMode.Linear, + KeyFrames = + { + new AnimationTrackProperty.KeyFrame(sprite.Rotation, 0), + new AnimationTrackProperty.KeyFrame(rotation, 0.125f) + } + } + } + }, "rotate"); + } + } +} diff --git a/Content.Client/GameObjects/Components/Mobs/BuckleVisualizer2D.cs b/Content.Client/GameObjects/Components/Mobs/BuckleVisualizer2D.cs deleted file mode 100644 index 755439c753..0000000000 --- a/Content.Client/GameObjects/Components/Mobs/BuckleVisualizer2D.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Content.Shared.GameObjects.Components.Mobs; -using Content.Shared.GameObjects.Components.Strap; -using JetBrains.Annotations; -using Robust.Client.GameObjects; -using Robust.Shared.Maths; - -namespace Content.Client.GameObjects.Components.Mobs -{ - [UsedImplicitly] - public class BuckleVisualizer2D : SpeciesVisualizer2D - { - public override void OnChangeData(AppearanceComponent component) - { - if (!component.TryGetData(SharedBuckleComponent.BuckleVisuals.Buckled, out var buckled) || - !buckled) - { - return; - } - - if (!component.TryGetData(StrapVisuals.RotationAngle, out var angle)) - { - return; - } - - SetRotation(component, Angle.FromDegrees(angle)); - } - } -} diff --git a/Content.Client/GameObjects/Components/Mobs/SpeciesVisualizer2D.cs b/Content.Client/GameObjects/Components/Mobs/SpeciesVisualizer2D.cs index 160b4cdf8e..cfd7e09596 100644 --- a/Content.Client/GameObjects/Components/Mobs/SpeciesVisualizer2D.cs +++ b/Content.Client/GameObjects/Components/Mobs/SpeciesVisualizer2D.cs @@ -29,7 +29,7 @@ namespace Content.Client.GameObjects.Components.Mobs } } - protected void SetRotation(AppearanceComponent component, Angle rotation) + private void SetRotation(AppearanceComponent component, Angle rotation) { var sprite = component.Owner.GetComponent(); diff --git a/Content.Client/GameObjects/Components/Strap/StrapComponent.cs b/Content.Client/GameObjects/Components/Strap/StrapComponent.cs index eabb96b01c..3eff3636e8 100644 --- a/Content.Client/GameObjects/Components/Strap/StrapComponent.cs +++ b/Content.Client/GameObjects/Components/Strap/StrapComponent.cs @@ -7,16 +7,5 @@ namespace Content.Client.GameObjects.Components.Strap [RegisterComponent] public class StrapComponent : SharedStrapComponent { - public override StrapPosition Position { get; protected set; } - - public override void HandleComponentState(ComponentState? curState, ComponentState? nextState) - { - if (!(curState is StrapComponentState strap)) - { - return; - } - - Position = strap.Position; - } } } diff --git a/Content.IntegrationTests/Tests/BuckleTest.cs b/Content.IntegrationTests/Tests/BuckleTest.cs new file mode 100644 index 0000000000..652950d600 --- /dev/null +++ b/Content.IntegrationTests/Tests/BuckleTest.cs @@ -0,0 +1,154 @@ +using System.Threading.Tasks; +using Content.Server.GameObjects.Components.Buckle; +using Content.Shared.GameObjects.Components.Buckle; +using Content.Shared.GameObjects.EntitySystems; +using NUnit.Framework; +using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.Interfaces.Map; +using Robust.Shared.IoC; +using Robust.Shared.Map; +using StrapComponent = Content.Server.GameObjects.Components.Strap.StrapComponent; + +namespace Content.IntegrationTests.Tests +{ + [TestFixture] + [TestOf(typeof(BuckleComponent))] + [TestOf(typeof(StrapComponent))] + public class BuckleTest : ContentIntegrationTest + { + [Test] + public async Task Test() + { + var server = StartServerDummyTicker(); + + IEntity human = null; + IEntity chair = null; + BuckleComponent buckle = null; + StrapComponent strap = null; + + server.Assert(() => + { + var mapManager = IoCManager.Resolve(); + + mapManager.CreateNewMapEntity(MapId.Nullspace); + + var entityManager = IoCManager.Resolve(); + + human = entityManager.SpawnEntity("HumanMob_Content", MapCoordinates.Nullspace); + chair = entityManager.SpawnEntity("ChairWood", MapCoordinates.Nullspace); + + // Default state, unbuckled + Assert.True(human.TryGetComponent(out buckle)); + Assert.NotNull(buckle); + Assert.Null(buckle.BuckledTo); + Assert.False(buckle.Buckled); + Assert.True(ActionBlockerSystem.CanMove(human)); + Assert.True(ActionBlockerSystem.CanChangeDirection(human)); + Assert.True(EffectBlockerSystem.CanFall(human)); + + // Default state, no buckled entities, strap + Assert.True(chair.TryGetComponent(out strap)); + Assert.NotNull(strap); + Assert.IsEmpty(strap.BuckledEntities); + Assert.Zero(strap.OccupiedSize); + + // Side effects of buckling + Assert.True(buckle.TryBuckle(human, chair)); + Assert.NotNull(buckle.BuckledTo); + Assert.True(buckle.Buckled); + Assert.True(((BuckleComponentState) buckle.GetComponentState()).Buckled); + Assert.False(ActionBlockerSystem.CanMove(human)); + Assert.False(ActionBlockerSystem.CanChangeDirection(human)); + Assert.False(EffectBlockerSystem.CanFall(human)); + Assert.AreEqual(human.Transform.WorldPosition, chair.Transform.WorldPosition); + + // Side effects of buckling for the strap + Assert.That(strap.BuckledEntities, Does.Contain(human)); + Assert.That(strap.OccupiedSize, Is.EqualTo(buckle.Size)); + Assert.Positive(strap.OccupiedSize); + + // Trying to buckle while already buckled fails + Assert.False(buckle.TryBuckle(human, chair)); + + // Trying to unbuckle too quickly fails + Assert.False(buckle.TryUnbuckle(human)); + Assert.False(buckle.ToggleBuckle(human, chair)); + Assert.True(buckle.Buckled); + }); + + // Wait enough ticks for the unbuckling cooldown to run out + server.RunTicks(60); + + server.Assert(() => + { + // Still buckled + Assert.True(buckle.Buckled); + + // Unbuckle + Assert.True(buckle.TryUnbuckle(human)); + Assert.Null(buckle.BuckledTo); + Assert.False(buckle.Buckled); + Assert.True(ActionBlockerSystem.CanMove(human)); + Assert.True(ActionBlockerSystem.CanChangeDirection(human)); + Assert.True(EffectBlockerSystem.CanFall(human)); + + // Unbuckle, strap + Assert.IsEmpty(strap.BuckledEntities); + Assert.Zero(strap.OccupiedSize); + + // Re-buckling has no cooldown + Assert.True(buckle.TryBuckle(human, chair)); + Assert.True(buckle.Buckled); + + // On cooldown + Assert.False(buckle.TryUnbuckle(human)); + Assert.True(buckle.Buckled); + Assert.False(buckle.ToggleBuckle(human, chair)); + Assert.True(buckle.Buckled); + Assert.False(buckle.ToggleBuckle(human, chair)); + Assert.True(buckle.Buckled); + }); + + // Wait enough ticks for the unbuckling cooldown to run out + server.RunTicks(60); + + server.Assert(() => + { + // Still buckled + Assert.True(buckle.Buckled); + + // Unbuckle + Assert.True(buckle.TryUnbuckle(human)); + Assert.False(buckle.Buckled); + + // Move away from the chair + human.Transform.WorldPosition += (1000, 1000); + + // Out of range + Assert.False(buckle.TryBuckle(human, chair)); + Assert.False(buckle.TryUnbuckle(human)); + Assert.False(buckle.ToggleBuckle(human, chair)); + + // Move near the chair + human.Transform.WorldPosition = chair.Transform.WorldPosition + (0.5f, 0); + + // In range + Assert.True(buckle.TryBuckle(human, chair)); + Assert.True(buckle.Buckled); + Assert.False(buckle.TryUnbuckle(human)); + Assert.True(buckle.Buckled); + Assert.False(buckle.ToggleBuckle(human, chair)); + Assert.True(buckle.Buckled); + + // Force unbuckle + Assert.True(buckle.TryUnbuckle(human, true)); + Assert.False(buckle.Buckled); + Assert.True(ActionBlockerSystem.CanMove(human)); + Assert.True(ActionBlockerSystem.CanChangeDirection(human)); + Assert.True(EffectBlockerSystem.CanFall(human)); + }); + + await server.WaitIdleAsync(); + } + } +} diff --git a/Content.Server/GameObjects/Components/Mobs/BuckleComponent.cs b/Content.Server/GameObjects/Components/Buckle/BuckleComponent.cs similarity index 77% rename from Content.Server/GameObjects/Components/Mobs/BuckleComponent.cs rename to Content.Server/GameObjects/Components/Buckle/BuckleComponent.cs index e8733b095b..1a2786a412 100644 --- a/Content.Server/GameObjects/Components/Mobs/BuckleComponent.cs +++ b/Content.Server/GameObjects/Components/Buckle/BuckleComponent.cs @@ -1,11 +1,13 @@ #nullable enable using System; +using Content.Server.GameObjects.Components.Mobs; using Content.Server.GameObjects.Components.Strap; using Content.Server.Interfaces; using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Mobs; using Content.Server.Utility; using Content.Shared.GameObjects; +using Content.Shared.GameObjects.Components.Buckle; using Content.Shared.GameObjects.Components.Mobs; using Content.Shared.GameObjects.Components.Strap; using Content.Shared.GameObjects.EntitySystems; @@ -22,7 +24,7 @@ using Robust.Shared.Maths; using Robust.Shared.Serialization; using Robust.Shared.ViewVariables; -namespace Content.Server.GameObjects.Components.Mobs +namespace Content.Server.GameObjects.Components.Buckle { [RegisterComponent] public class BuckleComponent : SharedBuckleComponent, IInteractHand, IDragDrop @@ -34,29 +36,32 @@ namespace Content.Server.GameObjects.Components.Mobs [Dependency] private readonly IServerNotifyManager _notifyManager = default!; #pragma warning restore 649 - /// - /// The amount of space that this entity occupies in a . - /// private int _size; /// /// The range from which this entity can buckle to a . /// + [ViewVariables] private float _range; /// /// The amount of time that must pass for this entity to /// be able to unbuckle after recently buckling. /// + [ViewVariables] private TimeSpan _unbuckleDelay; /// /// The time that this entity buckled at. /// + [ViewVariables] private TimeSpan _buckleTime; private StrapComponent? _buckledTo; + /// + /// The strap that this component is buckled to. + /// [ViewVariables] public StrapComponent? BuckledTo { @@ -70,13 +75,25 @@ namespace Content.Server.GameObjects.Components.Mobs } [ViewVariables] - protected override bool Buckled => BuckledTo != null; + public override bool Buckled => BuckledTo != null; - public bool ContainerChanged { get; private set; } + /// + /// True if the entity was inserted or removed from a container + /// before updating, false otherwise. + /// + [ViewVariables] + private bool ContainerChanged { get; set; } + /// + /// The amount of space that this entity occupies in a . + /// [ViewVariables] public int Size => _size; + /// + /// Shows or hides the buckled status effect depending on if the + /// entity is buckled or not. + /// private void BuckleStatus() { if (Owner.TryGetComponent(out ServerStatusEffectsComponent status)) @@ -88,6 +105,10 @@ namespace Content.Server.GameObjects.Components.Mobs } } + /// + /// Reattaches this entity to the strap, modifying its position and rotation + /// + /// The strap to reattach to private void ReAttach(StrapComponent strap) { var ownTransform = Owner.Transform; @@ -112,7 +133,18 @@ namespace Content.Server.GameObjects.Components.Mobs } } - private bool TryBuckle(IEntity user, IEntity to) + /// + /// Tries to make an entity buckle the owner of this component to another. + /// + /// + /// The entity buckling the owner of this component, can be the owner itself. + /// + /// The entity to buckle the owner of this component to. + /// + /// true if the owner was buckled, otherwise false even if the owner was + /// previously already buckled. + /// + public bool TryBuckle(IEntity user, IEntity to) { if (user == null || user == to) { @@ -142,8 +174,10 @@ namespace Content.Server.GameObjects.Components.Mobs return false; } + // If in a container if (ContainerHelpers.TryGetContainer(Owner, out var ownerContainer)) { + // And not in the same container as the strap if (!ContainerHelpers.TryGetContainer(strap.Owner, out var strapContainer) || ownerContainer != strapContainer) { @@ -218,6 +252,18 @@ namespace Content.Server.GameObjects.Components.Mobs return true; } + /// + /// Tries to unbuckle the Owner of this component from its current strap. + /// + /// The entity doing the unbuckling. + /// + /// Whether to force the unbuckling or not. Does not guarantee true to + /// be returned, but guarantees the owner to be unbuckled afterwards. + /// + /// + /// true if the owner was unbuckled, otherwise false even if the owner + /// was previously already unbuckled. + /// public bool TryUnbuckle(IEntity user, bool force = false) { if (BuckledTo == null) @@ -288,16 +334,35 @@ namespace Content.Server.GameObjects.Components.Mobs return true; } - public bool ToggleBuckle(IEntity user, IEntity to) + /// + /// Makes an entity toggle the buckling status of the owner to a + /// specific entity. + /// + /// The entity doing the buckling/unbuckling. + /// + /// The entity to toggle the buckle status of the owner to. + /// + /// + /// Whether to force the unbuckling or not, if it happens. Does not + /// guarantee true to be returned, but guarantees the owner to be + /// unbuckled afterwards. + /// + /// true if the buckling status was changed, false otherwise. + public bool ToggleBuckle(IEntity user, IEntity to, bool force = false) { if (BuckledTo?.Owner == to) { - return TryUnbuckle(user); + return TryUnbuckle(user, force); } return TryBuckle(user, to); } + /// + /// Called when the owner is inserted or removed from a container, + /// to synchronize the state of buckling. + /// + /// The message received private void InsertIntoContainer(ContainerModifiedMessage message) { if (message.Entity != Owner) @@ -308,6 +373,12 @@ namespace Content.Server.GameObjects.Components.Mobs ContainerChanged = true; } + /// + /// Synchronizes the state of buckling depending on whether the entity + /// was inserted or removed from a container, and whether or not + /// its current strap (if there is one) has also been put into or removed + /// from the same container as well. + /// public void Update() { if (!ContainerChanged || BuckledTo == null) @@ -401,6 +472,10 @@ namespace Content.Server.GameObjects.Components.Mobs return TryBuckle(eventArgs.User, eventArgs.Target); } + /// + /// Allows the unbuckling of the owning entity through a verb if + /// anyone right clicks them. + /// [Verb] private sealed class BuckleVerb : Verb { diff --git a/Content.Server/GameObjects/Components/Mobs/ServerStatusEffectsComponent.cs b/Content.Server/GameObjects/Components/Mobs/ServerStatusEffectsComponent.cs index 15acc85c78..ec1df766a1 100644 --- a/Content.Server/GameObjects/Components/Mobs/ServerStatusEffectsComponent.cs +++ b/Content.Server/GameObjects/Components/Mobs/ServerStatusEffectsComponent.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using Content.Server.GameObjects.Components.Buckle; using Content.Shared.GameObjects.Components.Mobs; using JetBrains.Annotations; using Robust.Shared.GameObjects; diff --git a/Content.Server/GameObjects/Components/Strap/StrapComponent.cs b/Content.Server/GameObjects/Components/Strap/StrapComponent.cs index c62c233b45..f2c8f42a8d 100644 --- a/Content.Server/GameObjects/Components/Strap/StrapComponent.cs +++ b/Content.Server/GameObjects/Components/Strap/StrapComponent.cs @@ -1,5 +1,5 @@ using System.Collections.Generic; -using Content.Server.GameObjects.Components.Mobs; +using Content.Server.GameObjects.Components.Buckle; using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Shared.GameObjects; using Content.Shared.GameObjects.Components.Strap; @@ -17,30 +17,34 @@ namespace Content.Server.GameObjects.Components.Strap [RegisterComponent] public class StrapComponent : SharedStrapComponent, IInteractHand { + private HashSet _buckledEntities; private StrapPosition _position; private string _buckleSound; private string _unbuckleSound; private string _buckledIcon; + + /// + /// The angle in degrees to rotate the player by when they get strapped + /// + [ViewVariables] private int _rotation; + + /// + /// The size of the strap which is compared against when buckling entities + /// + [ViewVariables] private int _size; + private int _occupiedSize; /// /// The entity that is currently buckled here, synced from /// - private HashSet BuckledEntities { get; set; } + public IReadOnlyCollection BuckledEntities => _buckledEntities; /// /// The change in position to the strapped mob /// - public override StrapPosition Position - { - get => _position; - protected set - { - _position = value; - Dirty(); - } - } + public StrapPosition Position => _position; /// /// The sound to be played when a mob is buckled @@ -60,34 +64,29 @@ namespace Content.Server.GameObjects.Components.Strap [ViewVariables] public string BuckledIcon => _buckledIcon; - /// - /// The angle in degrees to rotate the player by when they get strapped - /// - [ViewVariables] - public int Rotation => _rotation; - - /// - /// The size of the strap which is compared against when buckling entities - /// - [ViewVariables] - public int Size => _size; - /// /// The sum of the sizes of all the buckled entities in this strap /// [ViewVariables] - private int OccupiedSize { get; set; } + public int OccupiedSize => _occupiedSize; + /// + /// Checks if this strap has enough space for a new occupant. + /// + /// The new occupant + /// true if there is enough space, false otherwise public bool HasSpace(BuckleComponent buckle) { return OccupiedSize + buckle.Size <= _size; } /// - /// Adds a buckled entity. Called from + /// Adds a buckled entity. Called from /// /// The component to add - /// Whether or not to check if the strap has enough space + /// + /// Whether or not to check if the strap has enough space + /// /// True if added, false otherwise public bool TryAdd(BuckleComponent buckle, bool force = false) { @@ -96,12 +95,12 @@ namespace Content.Server.GameObjects.Components.Strap return false; } - if (!BuckledEntities.Add(buckle.Owner)) + if (!_buckledEntities.Add(buckle.Owner)) { return false; } - OccupiedSize += buckle.Size; + _occupiedSize += buckle.Size; if (buckle.Owner.TryGetComponent(out AppearanceComponent appearance)) { @@ -112,14 +111,15 @@ namespace Content.Server.GameObjects.Components.Strap } /// - /// Removes a buckled entity. Called from + /// Removes a buckled entity. + /// Called from /// /// The component to remove public void Remove(BuckleComponent buckle) { - if (BuckledEntities.Remove(buckle.Owner)) + if (_buckledEntities.Remove(buckle.Owner)) { - OccupiedSize -= buckle.Size; + _occupiedSize -= buckle.Size; } } @@ -136,16 +136,16 @@ namespace Content.Server.GameObjects.Components.Strap var defaultSize = 100; serializer.DataField(ref _size, "size", defaultSize); - BuckledEntities = new HashSet(_size / defaultSize); + _buckledEntities = new HashSet(_size / defaultSize); - OccupiedSize = 0; + _occupiedSize = 0; } public override void OnRemove() { base.OnRemove(); - foreach (var entity in BuckledEntities) + foreach (var entity in _buckledEntities) { if (entity.TryGetComponent(out BuckleComponent buckle)) { @@ -153,13 +153,8 @@ namespace Content.Server.GameObjects.Components.Strap } } - BuckledEntities.Clear(); - OccupiedSize = 0; - } - - public override ComponentState GetComponentState() - { - return new StrapComponentState(Position); + _buckledEntities.Clear(); + _occupiedSize = 0; } bool IInteractHand.InteractHand(InteractHandEventArgs eventArgs) diff --git a/Content.Server/GameObjects/EntitySystems/BuckleSystem.cs b/Content.Server/GameObjects/EntitySystems/BuckleSystem.cs index 133e8eb652..501ab2b9bb 100644 --- a/Content.Server/GameObjects/EntitySystems/BuckleSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/BuckleSystem.cs @@ -1,4 +1,5 @@ -using Content.Server.GameObjects.Components.Mobs; +using Content.Server.GameObjects.Components.Buckle; +using Content.Server.GameObjects.Components.Mobs; using Content.Server.GameObjects.EntitySystems.Click; using Robust.Server.GameObjects.EntitySystems; using Robust.Shared.GameObjects; diff --git a/Content.Shared/GameObjects/Components/Mobs/SharedBuckleComponent.cs b/Content.Shared/GameObjects/Components/Buckle/SharedBuckleComponent.cs similarity index 50% rename from Content.Shared/GameObjects/Components/Mobs/SharedBuckleComponent.cs rename to Content.Shared/GameObjects/Components/Buckle/SharedBuckleComponent.cs index 7cb6b760f7..39c5fd4cbf 100644 --- a/Content.Shared/GameObjects/Components/Mobs/SharedBuckleComponent.cs +++ b/Content.Shared/GameObjects/Components/Buckle/SharedBuckleComponent.cs @@ -3,7 +3,7 @@ using Content.Shared.GameObjects.EntitySystems; using Robust.Shared.GameObjects; using Robust.Shared.Serialization; -namespace Content.Shared.GameObjects.Components.Mobs +namespace Content.Shared.GameObjects.Components.Buckle { public abstract class SharedBuckleComponent : Component, IActionBlocker, IEffectBlocker { @@ -11,7 +11,10 @@ namespace Content.Shared.GameObjects.Components.Mobs public sealed override uint? NetID => ContentNetIDs.BUCKLE; - protected abstract bool Buckled { get; } + /// + /// True if the entity is buckled, false otherwise. + /// + public abstract bool Buckled { get; } bool IActionBlocker.CanMove() { @@ -27,24 +30,24 @@ namespace Content.Shared.GameObjects.Components.Mobs { return !Buckled; } + } - [Serializable, NetSerializable] - protected sealed class BuckleComponentState : ComponentState + [Serializable, NetSerializable] + public sealed class BuckleComponentState : ComponentState + { + public BuckleComponentState(bool buckled, int? drawDepth) : base(ContentNetIDs.BUCKLE) { - public BuckleComponentState(bool buckled, int? drawDepth) : base(ContentNetIDs.BUCKLE) - { - Buckled = buckled; - DrawDepth = drawDepth; - } - - public bool Buckled { get; } - public int? DrawDepth; + Buckled = buckled; + DrawDepth = drawDepth; } - [Serializable, NetSerializable] - public enum BuckleVisuals - { - Buckled - } + public bool Buckled { get; } + public int? DrawDepth; + } + + [Serializable, NetSerializable] + public enum BuckleVisuals + { + Buckled } } diff --git a/Content.Shared/GameObjects/Components/Strap/SharedStrapComponent.cs b/Content.Shared/GameObjects/Components/Strap/SharedStrapComponent.cs index 4ec1463c1a..64d895efa0 100644 --- a/Content.Shared/GameObjects/Components/Strap/SharedStrapComponent.cs +++ b/Content.Shared/GameObjects/Components/Strap/SharedStrapComponent.cs @@ -27,21 +27,6 @@ namespace Content.Shared.GameObjects.Components.Strap public sealed override string Name => "Strap"; public sealed override uint? NetID => ContentNetIDs.STRAP; - - public abstract StrapPosition Position { get; protected set; } - } - - [Serializable, NetSerializable] - public sealed class StrapComponentState : ComponentState - { - public readonly StrapPosition Position; - - public StrapComponentState(StrapPosition position) : base(ContentNetIDs.BUCKLE) - { - Position = position; - } - - public bool Buckled { get; } } [Serializable, NetSerializable] diff --git a/Resources/Prototypes/Entities/Mobs/human.yml b/Resources/Prototypes/Entities/Mobs/human.yml index 1334d119cb..f7db6f6d2b 100644 --- a/Resources/Prototypes/Entities/Mobs/human.yml +++ b/Resources/Prototypes/Entities/Mobs/human.yml @@ -127,7 +127,7 @@ - type: Appearance visuals: - type: SpeciesVisualizer2D - - type: BuckleVisualizer2D + - type: BuckleVisualizer - type: CombatMode - type: Teleportable - type: CharacterInfo