From fa452ffd41719eceb391e56b0ce0635d769e5a2f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers <coelckers@zdoom.fake> Date: Wed, 30 Dec 2009 18:53:14 +0000 Subject: [PATCH] - My ActorMover fix from earlier today was causing problems with moving sectors because it exposed a design flaw in the thinker system: Having every single actor default to the highest available statnum means that nothing can be placed in a slot where it is guaranteed to be run after all actors have ticked. But this is required for any thinker that moves an actor (i.e. AActorMover and DSectorEffect.) With DSectorEffect it just went unnoticed because they were added at the end of the list so almost nothing they moved was behind them in a thinker list. However, when an actor was spawned on a moving floor it did not move smoothly. The default statnum is now 100 so that there's sufficient slots above where such thinkers can be placed. SVN r2060 (trunk) --- docs/rh-log.txt | 9 +++++++ src/actor.h | 4 ---- src/dsectoreffect.cpp | 2 ++ src/dthinker.h | 3 ++- src/g_shared/a_movingcamera.cpp | 1 + src/p_enemy.cpp | 10 ++++---- src/p_map.cpp | 6 ++--- src/p_mobj.cpp | 42 +++++++++++++-------------------- src/p_spec.cpp | 10 ++++---- src/p_things.cpp | 6 ++--- src/statnums.h | 8 +++++++ 11 files changed, 53 insertions(+), 48 deletions(-) diff --git a/docs/rh-log.txt b/docs/rh-log.txt index a7a16b7ba..fae4f4cc5 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -3,6 +3,15 @@ December 30, 2009 (Changes by Graf Zahl) it happened outside the moved actor's Tick function. This got particularly obvious with moving skybox viewpoints (See Daedalus's MAP21 intro for a good example.) + Fixing this exposed a design flaw in the thinker system: + Having every single actor default to the highest available statnum means that + nothing can be placed in a slot where it is guaranteed to be run after all actors + have ticked. But this is required for any thinker that moves an actor + (i.e. AActorMover and DSectorEffect.) With DSectorEffect it just went unnoticed + because they were added at the end of the list so almost nothing they moved was + behind them in a thinker list. However, when an actor was spawned on a moving + floor it did not move smoothly. The default statnum is now 100 so that there's + sufficient slots above where such thinkers can be placed. December 28, 2009 - Fixed: Shooting up and down with AArtiPoisonBag3::Use() was completely diff --git a/src/actor.h b/src/actor.h index 90f80be1e..5fd0619b9 100644 --- a/src/actor.h +++ b/src/actor.h @@ -580,7 +580,6 @@ public: virtual void Deactivate (AActor *activator); virtual void Tick (); - void DoTick (); // Smallest yaw interval for a mapthing to be spawned with virtual angle_t AngleIncrements (); @@ -872,9 +871,6 @@ public: fixed_t PrevX, PrevY, PrevZ; angle_t PrevAngle; - fixed_t LastX, LastY, LastZ; - angle_t LastAngle; - // ThingIDs static void ClearTIDHashes (); void AddToHash (); diff --git a/src/dsectoreffect.cpp b/src/dsectoreffect.cpp index 48e58d0a9..2f4af7359 100644 --- a/src/dsectoreffect.cpp +++ b/src/dsectoreffect.cpp @@ -27,12 +27,14 @@ #include "p_local.h" #include "p_3dmidtex.h" #include "r_interpolate.h" +#include "statnums.h" IMPLEMENT_CLASS (DSectorEffect) DSectorEffect::DSectorEffect () { m_Sector = NULL; + ChangeStatNum(STAT_SECTOREFFECT); } void DSectorEffect::Destroy() diff --git a/src/dthinker.h b/src/dthinker.h index e50141475..32857d86b 100644 --- a/src/dthinker.h +++ b/src/dthinker.h @@ -36,6 +36,7 @@ #include <stdlib.h> #include "dobject.h" +#include "statnums.h" class AActor; class player_t; @@ -62,7 +63,7 @@ class DThinker : public DObject { DECLARE_CLASS (DThinker, DObject) public: - DThinker (int statnum = MAX_STATNUM) throw(); + DThinker (int statnum = STAT_DEFAULT) throw(); void Destroy (); virtual ~DThinker (); virtual void Tick (); diff --git a/src/g_shared/a_movingcamera.cpp b/src/g_shared/a_movingcamera.cpp index 55316dbf1..58bde3cff 100644 --- a/src/g_shared/a_movingcamera.cpp +++ b/src/g_shared/a_movingcamera.cpp @@ -213,6 +213,7 @@ void APathFollower::BeginPlay () Super::BeginPlay (); PrevNode = CurrNode = NULL; bActive = false; + ChangeStatNum(STAT_ACTORMOVER); } void APathFollower::PostBeginPlay () diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index 0b5c29137..4b80d5b68 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -523,9 +523,9 @@ bool P_Move (AActor *actor) // so make it switchable if (nomonsterinterpolation) { - actor->LastX = actor->PrevX = actor->x; - actor->LastY = actor->PrevY = actor->y; - actor->LastZ = actor->PrevZ = actor->z; + actor->PrevX = actor->x; + actor->PrevY = actor->y; + actor->PrevZ = actor->z; } if (try_ok && friction > ORIG_FRICTION) @@ -2435,8 +2435,8 @@ void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missi { if (nomonsterinterpolation) { - actor->LastX = actor->PrevX = oldX; - actor->LastY = actor->PrevY = oldY; + actor->PrevX = oldX; + actor->PrevY = oldY; } } P_NewChaseDir (actor); diff --git a/src/p_map.cpp b/src/p_map.cpp index 0750050e9..dc056972f 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -392,9 +392,9 @@ bool P_TeleportMove (AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefr R_ResetViewInterpolation (); } - thing->LastX = thing->PrevX = x; - thing->LastY = thing->PrevY = y; - thing->LastZ = thing->PrevZ = z; + thing->PrevX = x; + thing->PrevY = y; + thing->PrevZ = z; return true; } diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 82d8120b7..57ba84030 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -434,10 +434,10 @@ void AActor::Serialize (FArchive &arc) Speed = GetDefault()->Speed; } } - LastX = PrevX = x; - LastY = PrevY = y; - LastZ = PrevZ = z; - LastAngle = PrevAngle = angle; + PrevX = x; + PrevY = y; + PrevZ = z; + PrevAngle = angle; UpdateWaterLevel(z, false); } } @@ -2806,7 +2806,7 @@ void AActor::SetShade (int r, int g, int b) // // P_MobjThinker // -void AActor::DoTick () +void AActor::Tick () { // [RH] Data for Heretic/Hexen scrolling sectors static const BYTE HexenScrollDirs[8] = { 64, 0, 192, 128, 96, 32, 224, 160 }; @@ -2836,6 +2836,13 @@ void AActor::DoTick () return; } + // This is necessary to properly interpolate movement outside this function + // like from an ActorMover + PrevX = x; + PrevY = y; + PrevZ = z; + PrevAngle = angle; + if (flags5 & MF5_NOINTERACTION) { // only do the minimally necessary things here to save time: @@ -3375,23 +3382,6 @@ void AActor::DoTick () } } -void AActor::Tick() -{ - // This is necessary to properly interpolate movement outside this function - // like from an ActorMover - PrevX = LastX; - PrevY = LastY; - PrevZ = LastZ; - PrevAngle = LastAngle; - - DoTick(); - - LastX = x; - LastY = y; - LastZ = z; - LastAngle = angle; -} - //========================================================================== // // AActor::UpdateWaterLevel @@ -3531,9 +3521,9 @@ AActor *AActor::StaticSpawn (const PClass *type, fixed_t ix, fixed_t iy, fixed_t actor = static_cast<AActor *>(const_cast<PClass *>(type)->CreateNew ()); - actor->x = actor->LastX = actor->PrevX = ix; - actor->y = actor->LastY = actor->PrevY = iy; - actor->z = actor->LastZ = actor->PrevZ = iz; + actor->x = actor->PrevX = ix; + actor->y = actor->PrevY = iy; + actor->z = actor->PrevZ = iz; actor->picnum.SetInvalid(); actor->health = actor->SpawnHealth(); @@ -4418,7 +4408,7 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) mobj->tid = mthing->thingid; mobj->AddToHash (); - mobj->LastAngle = mobj->PrevAngle = mobj->angle = (DWORD)((mthing->angle * UCONST64(0x100000000)) / 360); + mobj->PrevAngle = mobj->angle = (DWORD)((mthing->angle * UCONST64(0x100000000)) / 360); mobj->BeginPlay (); if (!(mobj->ObjectFlags & OF_EuthanizeMe)) { diff --git a/src/p_spec.cpp b/src/p_spec.cpp index 487fff482..c78e4ebe3 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -898,16 +898,14 @@ void P_SetupPortals() fixed_t deltay2 = points[j]->Mate->y - points[j]->y; if (deltax1 == deltax2 && deltay1 == deltay2) { - if (points[j]->Sector->FloorSkyBox == points[j]) - points[j]->Sector->FloorSkyBox == points[i]; + if (points[j]->Sector->FloorSkyBox == points[j]->Mate) + points[j]->Sector->FloorSkyBox = points[i]->Mate; - if (points[j]->Sector->CeilingSkyBox == points[j]) - points[j]->Sector->CeilingSkyBox == points[i]; + if (points[j]->Sector->CeilingSkyBox == points[j]->Mate) + points[j]->Sector->CeilingSkyBox = points[i]->Mate; points[j]->special1 = 1; - break; } - } } } diff --git a/src/p_things.cpp b/src/p_things.cpp index 46c46be99..cd1540f4f 100644 --- a/src/p_things.cpp +++ b/src/p_things.cpp @@ -142,9 +142,9 @@ bool P_MoveThing(AActor *source, fixed_t x, fixed_t y, fixed_t z, bool fog) Spawn<ATeleportFog> (x, y, z + TELEFOGHEIGHT, ALLOW_REPLACE); Spawn<ATeleportFog> (oldx, oldy, oldz + TELEFOGHEIGHT, ALLOW_REPLACE); } - source->LastX = source->PrevX = x; - source->LastY = source->PrevY = y; - source->LastZ = source->PrevZ = z; + source->PrevX = x; + source->PrevY = y; + source->PrevZ = z; return true; } else diff --git a/src/statnums.h b/src/statnums.h index fd6831dc8..201b586da 100644 --- a/src/statnums.h +++ b/src/statnums.h @@ -1,3 +1,5 @@ +#ifndef __STATNUMS_H +#define __STATNUMS_H /* ** statnums.h ** @@ -56,4 +58,10 @@ enum STAT_LIGHTTRANSFER, // A sector light transfer. These must be ticked after the light effects!!! STAT_EARTHQUAKE, // Earthquake actors STAT_MAPMARKER, // Map marker actors + + STAT_DEFAULT = 100, + STAT_SECTOREFFECT, + STAT_ACTORMOVER, }; + +#endif \ No newline at end of file