From 5769beafdd4b2061d20f09bc819dbb8ac49f6072 Mon Sep 17 00:00:00 2001 From: wixoa Date: Wed, 10 Jan 2024 15:14:03 -0500 Subject: [PATCH] Handle `glide_size` being updated mid-glide (#1616) --- OpenDreamClient/Rendering/AtomGlideSystem.cs | 20 +++++++++++++------- OpenDreamRuntime/AtomManager.cs | 2 +- OpenDreamRuntime/Procs/DMOpcodeHandlers.cs | 3 +-- OpenDreamShared/Dream/IconAppearance.cs | 2 +- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/OpenDreamClient/Rendering/AtomGlideSystem.cs b/OpenDreamClient/Rendering/AtomGlideSystem.cs index a0b072132a..72a3ba8edb 100644 --- a/OpenDreamClient/Rendering/AtomGlideSystem.cs +++ b/OpenDreamClient/Rendering/AtomGlideSystem.cs @@ -8,10 +8,10 @@ namespace OpenDreamClient.Rendering; /// Disables RobustToolbox's transform lerping and replaces it with our own gliding /// public sealed class AtomGlideSystem : EntitySystem { - private sealed class Glide(TransformComponent transform) { + private sealed class Glide(TransformComponent transform, DMISpriteComponent sprite) { public readonly TransformComponent Transform = transform; + public readonly DMISpriteComponent Sprite = sprite; public Vector2 EndPos; - public float MovementSpeed; } [Dependency] private readonly TransformSystem _transformSystem = default!; @@ -42,9 +42,16 @@ public override void FrameUpdate(float frameTime) { for (int i = 0; i < _currentGlides.Count; i++) { var glide = _currentGlides[i]; + + if (glide.Sprite.Icon.Appearance == null) { + _currentGlides.RemoveSwap(i--); + continue; + } + var currentPos = glide.Transform.LocalPosition; var newPos = currentPos; - var movement = glide.MovementSpeed * frameTime; + var movementSpeed = CalculateMovementSpeed(glide.Sprite.Icon.Appearance.GlideSize); + var movement = movementSpeed * frameTime; // Move X towards the end position at a constant speed if (!MathHelper.CloseTo(currentPos.X, glide.EndPos.X)) { @@ -111,7 +118,7 @@ private void OnTransformMove(ref MoveEvent e) { } if (glide == null) { - glide = new(e.Component); + glide = new(e.Component, sprite); _currentGlides.Add(glide); } @@ -120,16 +127,15 @@ private void OnTransformMove(ref MoveEvent e) { _transformSystem.SetLocalPositionNoLerp(e.Sender, startingFrom, e.Component); glide.EndPos = glidingTo; - glide.MovementSpeed = CalculateMovementSpeed(sprite.Icon.Appearance.GlideSize); _ignoreMoveEvent = false; } - private static float CalculateMovementSpeed(byte glideSize) { + private static float CalculateMovementSpeed(float glideSize) { if (glideSize == 0) glideSize = 4; // TODO: 0 gives us "automated control" over this value, not just setting it to 4 // Assume a 20 TPS server // TODO: Support other TPS - return (float)glideSize / EyeManager.PixelsPerMeter * 20f; + return glideSize / EyeManager.PixelsPerMeter * 20f; } } diff --git a/OpenDreamRuntime/AtomManager.cs b/OpenDreamRuntime/AtomManager.cs index cdc5d03c2a..35a8dd3bad 100644 --- a/OpenDreamRuntime/AtomManager.cs +++ b/OpenDreamRuntime/AtomManager.cs @@ -328,7 +328,7 @@ public void SetAppearanceVar(IconAppearance appearance, string varName, DreamVal break; case "glide_size": value.TryGetValueAsFloat(out float glideSize); - appearance.GlideSize = (byte) glideSize; + appearance.GlideSize = glideSize; break; case "render_source": value.TryGetValueAsString(out appearance.RenderSource); diff --git a/OpenDreamRuntime/Procs/DMOpcodeHandlers.cs b/OpenDreamRuntime/Procs/DMOpcodeHandlers.cs index 40a5f7049f..ecd3ddce4c 100644 --- a/OpenDreamRuntime/Procs/DMOpcodeHandlers.cs +++ b/OpenDreamRuntime/Procs/DMOpcodeHandlers.cs @@ -1697,14 +1697,13 @@ public static ProcStatus SwitchCaseRange(DMProcState state) { public static ProcStatus Spawn(DMProcState state) { int jumpTo = state.ReadInt(); state.Pop().TryGetValueAsFloat(out var delay); - int delayMilliseconds = (int)(delay * 100); // TODO: It'd be nicer if we could use something such as DreamThread.Spawn here // and have state.Spawn return a ProcState instead DreamThread newContext = state.Spawn(); //Negative delays mean the spawned code runs immediately - if (delayMilliseconds < 0) { + if (delay < 0) { newContext.Resume(); // TODO: Does the rest of the proc get scheduled? // Does the value of the delay mean anything? diff --git a/OpenDreamShared/Dream/IconAppearance.cs b/OpenDreamShared/Dream/IconAppearance.cs index e82c044d24..7847f6d742 100644 --- a/OpenDreamShared/Dream/IconAppearance.cs +++ b/OpenDreamShared/Dream/IconAppearance.cs @@ -17,7 +17,7 @@ public sealed class IconAppearance : IEquatable { [ViewVariables] public Vector2i PixelOffset; [ViewVariables] public Color Color = Color.White; [ViewVariables] public byte Alpha = 255; - [ViewVariables] public byte GlideSize; + [ViewVariables] public float GlideSize; /// /// An appearance can gain a color matrix filter by two possible forces:
/// 1. the /atom.color var is modified.