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 #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(const_cast(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 (x, y, z + TELEFOGHEIGHT, ALLOW_REPLACE); Spawn (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