From 14ea9efc9732d39488340d00574e508eba51ec5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Sun, 7 Jul 2024 10:54:49 -0300 Subject: [PATCH] handle freeze in decoupled animations --- src/playsim/actor.h | 2 +- src/playsim/p_actionfunctions.cpp | 8 +++++--- src/playsim/p_mobj.cpp | 14 +++++++++++++- src/r_data/models.cpp | 4 ++-- 4 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/playsim/actor.h b/src/playsim/actor.h index ece9be8e081..4a0a3cf1471 100644 --- a/src/playsim/actor.h +++ b/src/playsim/actor.h @@ -710,7 +710,7 @@ struct AnimOverride int flags = ANIMOVERRIDE_NONE; float framerate; double startTic; // when the current animation started (changing framerates counts as restarting) (or when animation starts if interpolating from previous animation) - double switchTic; // when the animation was changed -- where to interpolate the switch from + double switchOffset; // when the animation was changed -- where to interpolate the switch from }; struct ModelOverride diff --git a/src/playsim/p_actionfunctions.cpp b/src/playsim/p_actionfunctions.cpp index b6090213b34..4a647af4efd 100644 --- a/src/playsim/p_actionfunctions.cpp +++ b/src/playsim/p_actionfunctions.cpp @@ -5214,18 +5214,20 @@ void SetAnimationInternal(AActor * self, FName animName, double framerate, int s self->modelData->curAnim.startFrame = startFrame < 0 ? animStart : animStart + startFrame; self->modelData->curAnim.loopFrame = loopFrame < 0 ? animStart : animStart + loopFrame; self->modelData->curAnim.flags = (flags&SAF_LOOP) ? ANIMOVERRIDE_LOOP : 0; - self->modelData->curAnim.switchTic = tic; self->modelData->curAnim.framerate = (float)framerate; if(!(flags & SAF_INSTANT)) { self->modelData->prevAnim.startFrame = getCurrentFrame(self->modelData->prevAnim, tic); - self->modelData->curAnim.startTic = floor(tic) + interpolateTics; + int startTic = floor(tic) + interpolateTics; + self->modelData->curAnim.startTic = startTic; + self->modelData->curAnim.switchOffset = startTic - tic; } else { self->modelData->curAnim.startTic = tic; + self->modelData->curAnim.switchOffset = 0; } } @@ -5274,7 +5276,7 @@ void SetAnimationFrameRateInternal(AActor * self, double framerate, double ticFr self->modelData->curAnim.startFrame = frame; self->modelData->curAnim.startTic = tic; - self->modelData->curAnim.switchTic = tic; + self->modelData->curAnim.switchOffset = 0; self->modelData->curAnim.framerate = (float)framerate; } diff --git a/src/playsim/p_mobj.cpp b/src/playsim/p_mobj.cpp index 728f1a56de4..3f08d3a39bd 100644 --- a/src/playsim/p_mobj.cpp +++ b/src/playsim/p_mobj.cpp @@ -1453,7 +1453,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, struct AnimOverride &a arc("flags", ao.flags); arc("framerate", ao.framerate); arc("startTic", ao.startTic); - arc("switchTic", ao.switchTic); + arc("switchOffset", ao.switchOffset); arc.EndObject(); return arc; } @@ -3861,6 +3861,12 @@ void AActor::Tick () { special2++; } + + if(flags9 & MF9_DECOUPLEDANIMATIONS && modelData && !(modelData->curAnim.flags & ANIMOVERRIDE_NONE)) + { + modelData->curAnim.startTic += 1; + } + return; } @@ -3908,6 +3914,12 @@ void AActor::Tick () { special2++; } + + if(flags9 & MF9_DECOUPLEDANIMATIONS && modelData && !(modelData->curAnim.flags & ANIMOVERRIDE_NONE)) + { + modelData->curAnim.startTic += 1; + } + return; } diff --git a/src/r_data/models.cpp b/src/r_data/models.cpp index f63a15ef6a2..abf1bf179a6 100644 --- a/src/r_data/models.cpp +++ b/src/r_data/models.cpp @@ -316,13 +316,13 @@ void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpr if(actor->modelData && !(actor->modelData->curAnim.flags & ANIMOVERRIDE_NONE)) { double tic = actor->Level->totaltime; - if ((ConsoleState == c_up || ConsoleState == c_rising) && (menuactive == MENU_Off || menuactive == MENU_OnNoPause) && !Level->isFrozen()) + if ((ConsoleState == c_up || ConsoleState == c_rising) && (menuactive == MENU_Off || menuactive == MENU_OnNoPause) && !actor->isFrozen()) { tic += I_GetTimeFrac(); } if(actor->modelData->curAnim.startTic > tic) { - inter = (tic - actor->modelData->curAnim.switchTic) / (actor->modelData->curAnim.startTic - actor->modelData->curAnim.switchTic); + inter = (tic - (actor->modelData->curAnim.startTic - actor->modelData->curAnim.switchOffset)) / actor->modelData->curAnim.switchOffset; double nextFrame = actor->modelData->curAnim.startFrame;