diff --git a/.github/workflows/rsi-diff.yml b/.github/workflows/rsi-diff.yml index 1f122526d7..98cc97e922 100644 --- a/.github/workflows/rsi-diff.yml +++ b/.github/workflows/rsi-diff.yml @@ -15,9 +15,12 @@ jobs: - name: Get changed files id: files - uses: Ana06/get-changed-files@v1.2 + uses: Ana06/get-changed-files@v2.3.0 with: format: 'space-delimited' + filter: | + **.rsi + **.png - name: Diff changed RSIs id: diff diff --git a/Content.Client/Buckle/BuckleSystem.cs b/Content.Client/Buckle/BuckleSystem.cs index fea18e5cf3..6770899e0a 100644 --- a/Content.Client/Buckle/BuckleSystem.cs +++ b/Content.Client/Buckle/BuckleSystem.cs @@ -3,6 +3,7 @@ using Content.Shared.Buckle; using Content.Shared.Buckle.Components; using Content.Shared.Rotation; using Robust.Client.GameObjects; +using Robust.Shared.GameStates; namespace Content.Client.Buckle; @@ -14,40 +15,63 @@ internal sealed class BuckleSystem : SharedBuckleSystem { base.Initialize(); - SubscribeLocalEvent(OnBuckleAfterAutoHandleState); + SubscribeLocalEvent(OnHandleState); SubscribeLocalEvent(OnAppearanceChange); + SubscribeLocalEvent(OnStrapMoveEvent); } - private void OnBuckleAfterAutoHandleState(EntityUid uid, BuckleComponent component, ref AfterAutoHandleStateEvent args) + private void OnStrapMoveEvent(EntityUid uid, StrapComponent component, ref MoveEvent args) { - ActionBlocker.UpdateCanMove(uid); + // I'm moving this to the client-side system, but for the sake of posterity let's keep this comment: + // > This is mega cursed. Please somebody save me from Mr Buckle's wild ride - if (!TryComp(uid, out var ownerSprite)) + // The nice thing is its still true, this is quite cursed, though maybe not omega cursed anymore. + // This code is garbage, it doesn't work with rotated viewports. I need to finally get around to reworking + // sprite rendering for entity layers & direction dependent sorting. + + if (args.NewRotation == args.OldRotation) return; - // Adjust draw depth when the chair faces north so that the seat back is drawn over the player. - // Reset the draw depth when rotated in any other direction. - // TODO when ECSing, make this a visualizer - // This code was written before rotatable viewports were introduced, so hard-coding Direction.North - // and comparing it against LocalRotation now breaks this in other rotations. This is a FIXME, but - // better to get it working for most people before we look at a more permanent solution. - if (component is { Buckled: true, LastEntityBuckledTo: { } } && - Transform(component.LastEntityBuckledTo.Value).LocalRotation.GetCardinalDir() == Direction.North && - TryComp(component.LastEntityBuckledTo, out var buckledSprite)) - { - component.OriginalDrawDepth ??= ownerSprite.DrawDepth; - ownerSprite.DrawDepth = buckledSprite.DrawDepth - 1; + if (!TryComp(uid, out var strapSprite)) return; - } - // If here, we're not turning north and should restore the saved draw depth. - if (component.OriginalDrawDepth.HasValue) + var isNorth = Transform(uid).LocalRotation.GetCardinalDir() == Direction.North; + foreach (var buckledEntity in component.BuckledEntities) { - ownerSprite.DrawDepth = component.OriginalDrawDepth.Value; - component.OriginalDrawDepth = null; + if (!TryComp(buckledEntity, out var buckle)) + continue; + + if (!TryComp(buckledEntity, out var buckledSprite)) + continue; + + if (isNorth) + { + buckle.OriginalDrawDepth ??= buckledSprite.DrawDepth; + buckledSprite.DrawDepth = strapSprite.DrawDepth - 1; + } + else if (buckle.OriginalDrawDepth.HasValue) + { + buckledSprite.DrawDepth = buckle.OriginalDrawDepth.Value; + buckle.OriginalDrawDepth = null; + } } } + private void OnHandleState(Entity ent, ref ComponentHandleState args) + { + if (args.Current is not BuckleState state) + return; + + ent.Comp.DontCollide = state.DontCollide; + ent.Comp.BuckleTime = state.BuckleTime; + var strapUid = EnsureEntity(state.BuckledTo, ent); + + SetBuckledTo(ent, strapUid == null ? null : new (strapUid.Value, null)); + + var (uid, component) = ent; + + } + private void OnAppearanceChange(EntityUid uid, BuckleComponent component, ref AppearanceChangeEvent args) { if (!TryComp(uid, out var rotVisuals)) diff --git a/Content.Client/Clothing/Systems/PilotedByClothingSystem.cs b/Content.Client/Clothing/Systems/PilotedByClothingSystem.cs new file mode 100644 index 0000000000..c04cf0a60b --- /dev/null +++ b/Content.Client/Clothing/Systems/PilotedByClothingSystem.cs @@ -0,0 +1,19 @@ +using Content.Shared.Clothing.Components; +using Robust.Client.Physics; + +namespace Content.Client.Clothing.Systems; + +public sealed partial class PilotedByClothingSystem : EntitySystem +{ + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnUpdatePredicted); + } + + private void OnUpdatePredicted(Entity entity, ref UpdateIsPredictedEvent args) + { + args.BlockPrediction = true; + } +} diff --git a/Content.Client/DeviceNetwork/Systems/DeviceNetworkJammerSystem.cs b/Content.Client/DeviceNetwork/Systems/DeviceNetworkJammerSystem.cs new file mode 100644 index 0000000000..39e03a17da --- /dev/null +++ b/Content.Client/DeviceNetwork/Systems/DeviceNetworkJammerSystem.cs @@ -0,0 +1,6 @@ +using Content.Shared.DeviceNetwork.Systems; + +namespace Content.Client.DeviceNetwork.Systems; + +/// +public sealed class DeviceNetworkJammerSystem : SharedDeviceNetworkJammerSystem; diff --git a/Content.Client/Effects/ColorFlashEffectSystem.cs b/Content.Client/Effects/ColorFlashEffectSystem.cs index af0bd4b600..956c946524 100644 --- a/Content.Client/Effects/ColorFlashEffectSystem.cs +++ b/Content.Client/Effects/ColorFlashEffectSystem.cs @@ -2,8 +2,10 @@ using Content.Shared.Effects; using Robust.Client.Animations; using Robust.Client.GameObjects; using Robust.Shared.Animations; +using Robust.Shared.Collections; using Robust.Shared.Player; using Robust.Shared.Timing; +using Robust.Shared.Utility; namespace Content.Client.Effects; @@ -11,13 +13,13 @@ public sealed class ColorFlashEffectSystem : SharedColorFlashEffectSystem { [Dependency] private readonly IGameTiming _timing = default!; [Dependency] private readonly AnimationPlayerSystem _animation = default!; - [Dependency] private readonly IComponentFactory _factory = default!; /// /// It's a little on the long side but given we use multiple colours denoting what happened it makes it easier to register. /// private const float AnimationLength = 0.30f; private const string AnimationKey = "color-flash-effect"; + private ValueList _toRemove = new(); public override void Initialize() { @@ -44,8 +46,28 @@ public sealed class ColorFlashEffectSystem : SharedColorFlashEffectSystem { sprite.Color = component.Color; } + } - RemCompDeferred(uid); + public override void Update(float frameTime) + { + base.Update(frameTime); + + var query = AllEntityQuery(); + _toRemove.Clear(); + + // Can't use deferred removal on animation completion or it will cause issues. + while (query.MoveNext(out var uid, out _)) + { + if (_animation.HasRunningAnimation(uid, AnimationKey)) + continue; + + _toRemove.Add(uid); + } + + foreach (var ent in _toRemove) + { + RemComp(ent); + } } private Animation? GetDamageAnimation(EntityUid uid, Color color, SpriteComponent? sprite = null) @@ -82,51 +104,31 @@ public sealed class ColorFlashEffectSystem : SharedColorFlashEffectSystem { var ent = GetEntity(nent); - if (Deleted(ent)) + if (Deleted(ent) || !TryComp(ent, out SpriteComponent? sprite)) { continue; } - if (!TryComp(ent, out AnimationPlayerComponent? player)) - { - player = (AnimationPlayerComponent) _factory.GetComponent(typeof(AnimationPlayerComponent)); - player.Owner = ent; - player.NetSyncEnabled = false; - AddComp(ent, player); - } - - // Need to stop the existing animation first to ensure the sprite color is fixed. - // Otherwise we might lerp to a red colour instead. - if (_animation.HasRunningAnimation(ent, player, AnimationKey)) - { - _animation.Stop(ent, player, AnimationKey); - } - - if (!TryComp(ent, out var sprite)) - { - continue; - } - - if (TryComp(ent, out var effect)) - { - sprite.Color = effect.Color; - } - - var animation = GetDamageAnimation(ent, color, sprite); - - if (animation == null) - continue; - if (!TryComp(ent, out ColorFlashEffectComponent? comp)) { - comp = (ColorFlashEffectComponent) _factory.GetComponent(typeof(ColorFlashEffectComponent)); - comp.Owner = ent; - comp.NetSyncEnabled = false; - AddComp(ent, comp); +#if DEBUG + DebugTools.Assert(!_animation.HasRunningAnimation(ent, AnimationKey)); +#endif } + _animation.Stop(ent, AnimationKey); + var animation = GetDamageAnimation(ent, color, sprite); + + if (animation == null) + { + continue; + } + + EnsureComp(ent, out comp); + comp.NetSyncEnabled = false; comp.Color = sprite.Color; - _animation.Play((ent, player), animation, AnimationKey); + + _animation.Play(ent, animation, AnimationKey); } } } diff --git a/Content.Client/Gravity/FloatingVisualizerSystem.cs b/Content.Client/Gravity/FloatingVisualizerSystem.cs index f489237d10..a7cb3333b2 100644 --- a/Content.Client/Gravity/FloatingVisualizerSystem.cs +++ b/Content.Client/Gravity/FloatingVisualizerSystem.cs @@ -57,6 +57,6 @@ public sealed class FloatingVisualizerSystem : SharedFloatingVisualizerSystem if (args.Key != component.AnimationKey) return; - FloatAnimation(uid, component.Offset, component.AnimationKey, component.AnimationTime, !component.CanFloat); + FloatAnimation(uid, component.Offset, component.AnimationKey, component.AnimationTime, stop: !component.CanFloat); } } diff --git a/Content.Client/Interaction/DragDropSystem.cs b/Content.Client/Interaction/DragDropSystem.cs index 8baa4d15fe..d249766bbc 100644 --- a/Content.Client/Interaction/DragDropSystem.cs +++ b/Content.Client/Interaction/DragDropSystem.cs @@ -495,7 +495,7 @@ public sealed class DragDropSystem : SharedDragDropSystem // CanInteract() doesn't support checking a second "target" entity. // Doing so manually: var ev = new GettingInteractedWithAttemptEvent(user, dragged); - RaiseLocalEvent(dragged, ev, true); + RaiseLocalEvent(dragged, ref ev); if (ev.Cancelled) return false; diff --git a/Content.Client/Lathe/UI/LatheMenu.xaml b/Content.Client/Lathe/UI/LatheMenu.xaml index 6f484d8c7b..e3247fe703 100644 --- a/Content.Client/Lathe/UI/LatheMenu.xaml +++ b/Content.Client/Lathe/UI/LatheMenu.xaml @@ -100,12 +100,11 @@ Margin="5 0 0 0" Text="{Loc 'lathe-menu-fabricating-message'}"> - - +