Skip to content

Commit

Permalink
Fix loop behaviour in animate() (#1801)
Browse files Browse the repository at this point in the history
Co-authored-by: amylizzle <[email protected]>
  • Loading branch information
amylizzle and amylizzle authored Sep 3, 2024
1 parent 637f3be commit d0d923b
Showing 1 changed file with 43 additions and 15 deletions.
58 changes: 43 additions & 15 deletions OpenDreamClient/Rendering/DreamIcon.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ private set {
private int _animationFrame;
private TimeSpan _animationFrameTime = gameTiming.CurTime;
private List<AppearanceAnimation>? _appearanceAnimations;
private int _appearanceAnimationsLoops;
private Box2? _cachedAABB;
private bool _textureDirty = true;
private IRenderTexture? _cachedTexture;
Expand Down Expand Up @@ -144,7 +145,19 @@ public void StartAppearanceAnimation(IconAppearance endingAppearance, TimeSpan d
start = _appearanceAnimations[^1].Start + _appearanceAnimations[^1].Duration; //if it's not parallel, it's chained

_appearanceAnimations ??= new List<AppearanceAnimation>();
_appearanceAnimations.Add(new AppearanceAnimation(start, duration, endingAppearance, easing, loops, flags, delay));
if(_appearanceAnimations.Count == 0) {//only valid on the first animation
_appearanceAnimationsLoops = loops;
}

for(int i=_appearanceAnimations.Count-1; i>=0; i--) //there can be only one last-in-sequence, and it might not be the last element of the list because it could be added to mid-loop
if(_appearanceAnimations[i].LastInSequence) {
var lastAnim = _appearanceAnimations[i];
lastAnim.LastInSequence = false;
_appearanceAnimations[i] = lastAnim;
break;
}

_appearanceAnimations.Add(new AppearanceAnimation(start, duration, endingAppearance, easing, flags, delay, true));
}

/// <summary>
Expand Down Expand Up @@ -188,6 +201,7 @@ public void GetWorldAABB(Vector2 worldPos, ref Box2? aabb) {
private void UpdateAnimation() {
if(DMI == null || Appearance == null)
return;

DMIParser.ParsedDMIState? dmiState = DMI.Description.GetStateOrDefault(Appearance.IconState);
if(dmiState == null)
return;
Expand All @@ -214,10 +228,11 @@ private void UpdateAnimation() {
_textureDirty = true; //if we have animations, we need to recalculate the texture
IconAppearance appearance = new IconAppearance(_appearance);
List<AppearanceAnimation>? toRemove = null;
List<AppearanceAnimation>? toReAdd = null;
for(int i = 0; i < _appearanceAnimations.Count; i++) {
AppearanceAnimation animation = _appearanceAnimations[i];
//if it's not the first one, and it's not parallel, break
if((animation.flags & AnimationFlags.AnimationParallel) == 0 && i != 0)
if((animation.Flags & AnimationFlags.AnimationParallel) == 0 && i != 0)
break;

float timeFactor = Math.Clamp((float)(DateTime.Now - animation.Start).Ticks / animation.Duration.Ticks, 0.0f, 1.0f);
Expand Down Expand Up @@ -390,21 +405,34 @@ private void UpdateAnimation() {
}

if (timeFactor >= 1f) {
if (animation.loops > 0) {
var tempAnimation = _appearanceAnimations[i];
tempAnimation.loops--;
_appearanceAnimations[i] = tempAnimation;
}
if (animation.loops == 0) {
toRemove ??= new();
toRemove.Add(animation);
toRemove ??= new();
toRemove.Add(animation);
if (_appearanceAnimationsLoops != 0) { //add it back to the list with the times updated
if(_appearanceAnimationsLoops != -1 && animation.LastInSequence)
_appearanceAnimationsLoops -= 1;
toReAdd ??= new();
DateTime start;
if((animation.Flags & AnimationFlags.AnimationParallel) != 0)
start = _appearanceAnimations[^1].Start; //either that's also a parallel, or its one that this should be parallel with
else
start = _appearanceAnimations[^1].Start + _appearanceAnimations[^1].Duration; //if it's not parallel, it's chained
AppearanceAnimation repeatAnimation = new AppearanceAnimation(start, animation.Duration, animation.EndAppearance, animation.Easing, animation.Flags, animation.Delay, animation.LastInSequence);
toReAdd.Add(repeatAnimation);
}

}
}

if(toRemove != null)
foreach (AppearanceAnimation animation in toRemove!) {
foreach (AppearanceAnimation animation in toRemove) {
EndAppearanceAnimation(animation);
}

if(toReAdd != null)
foreach (AppearanceAnimation animation in toReAdd) {
_appearanceAnimations.Add(animation);
}

return appearance;
}

Expand Down Expand Up @@ -506,13 +534,13 @@ private void DirtyTexture() {
CachedTexture = null;
}

private struct AppearanceAnimation(DateTime start, TimeSpan duration, IconAppearance endAppearance, AnimationEasing easing, int loops, AnimationFlags flags, int delay) {
private struct AppearanceAnimation(DateTime start, TimeSpan duration, IconAppearance endAppearance, AnimationEasing easing, AnimationFlags flags, int delay, bool lastInSequence) {
public readonly DateTime Start = start;
public readonly TimeSpan Duration = duration;
public readonly IconAppearance EndAppearance = endAppearance;
public readonly AnimationEasing Easing = easing;
public int loops = loops;
public readonly AnimationFlags flags = flags;
public int delay = delay;
public readonly AnimationFlags Flags = flags;
public readonly int Delay = delay;
public bool LastInSequence = lastInSequence;
}
}

0 comments on commit d0d923b

Please sign in to comment.