diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 92f5bca3b..aea95c4f4 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,4 +1,7 @@ March 12, 2008 (Changes by Graf Zahl) +- Changed DObject's pointer substitution so that the pointers inside an + object are handled by a virtual function. This allows subclasses to + implement their own handling if they need it. - Bumped the minimum savegame version because the current version crashes each time an old savegame is loaded. diff --git a/src/dobject.cpp b/src/dobject.cpp index 4bd7d4a2d..346089039 100644 --- a/src/dobject.cpp +++ b/src/dobject.cpp @@ -379,7 +379,7 @@ DObject::~DObject () } // Find all pointers that reference this object and NULL them. - PointerSubstitution(this, NULL); + StaticPointerSubstitution(this, NULL); // Now unlink this object from the GC list. for (probe = &GC::Root; *probe != NULL; probe = &((*probe)->ObjNext)) @@ -433,6 +433,25 @@ size_t DObject::PropagateMark() } void DObject::PointerSubstitution (DObject *old, DObject *notOld) +{ + const PClass *info = GetClass(); + const size_t *offsets = info->FlatPointers; + if (offsets == NULL) + { + const_cast(info)->BuildFlatPointers(); + offsets = info->FlatPointers; + } + while (*offsets != ~(size_t)0) + { + if (*(DObject **)((BYTE *)this + *offsets) == old) + { + *(DObject **)((BYTE *)this + *offsets) = notOld; + } + offsets++; + } +} + +void DObject::StaticPointerSubstitution (DObject *old, DObject *notOld) { DObject *probe; int i; @@ -440,21 +459,7 @@ void DObject::PointerSubstitution (DObject *old, DObject *notOld) // Go through all objects. for (probe = GC::Root; probe != NULL; probe = probe->ObjNext) { - const PClass *info = probe->GetClass(); - const size_t *offsets = info->FlatPointers; - if (offsets == NULL) - { - const_cast(info)->BuildFlatPointers(); - offsets = info->FlatPointers; - } - while (*offsets != ~(size_t)0) - { - if (*(DObject **)((BYTE *)probe + *offsets) == old) - { - *(DObject **)((BYTE *)probe + *offsets) = notOld; - } - offsets++; - } + probe->PointerSubstitution(old, notOld); } // Go through the bodyque. diff --git a/src/dobject.h b/src/dobject.h index b0ef5d708..00cd163d9 100644 --- a/src/dobject.h +++ b/src/dobject.h @@ -446,7 +446,8 @@ public: // If you need to replace one object with another and want to // change any pointers from the old object to the new object, // use this method. - static void PointerSubstitution (DObject *old, DObject *notOld); + virtual void PointerSubstitution (DObject *old, DObject *notOld); + static void StaticPointerSubstitution (DObject *old, DObject *notOld); PClass *GetClass() const { diff --git a/src/g_level.cpp b/src/g_level.cpp index a50303256..6e166fd29 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -2299,7 +2299,7 @@ void G_FinishTravel () pawn->target = NULL; pawn->lastenemy = NULL; pawn->player->mo = pawn; - DObject::PointerSubstitution (oldpawn, pawn); + DObject::StaticPointerSubstitution (oldpawn, pawn); oldpawn->Destroy(); pawndup->Destroy (); pawn->LinkToWorld (); diff --git a/src/g_shared/a_morph.cpp b/src/g_shared/a_morph.cpp index c091c5133..16c60f469 100644 --- a/src/g_shared/a_morph.cpp +++ b/src/g_shared/a_morph.cpp @@ -58,7 +58,7 @@ bool P_MorphPlayer (player_t *p, const PClass *spawntype) } morphed = static_cast(Spawn (spawntype, actor->x, actor->y, actor->z, NO_REPLACE)); - DObject::PointerSubstitution (actor, morphed); + DObject::StaticPointerSubstitution (actor, morphed); morphed->angle = actor->angle; morphed->target = actor->target; morphed->tracer = actor; @@ -151,7 +151,7 @@ bool P_UndoPlayerMorph (player_t *player, bool force) pmo->player = NULL; mo->ObtainInventory (pmo); - DObject::PointerSubstitution (pmo, mo); + DObject::StaticPointerSubstitution (pmo, mo); mo->angle = pmo->angle; mo->player = player; mo->reactiontime = 18; @@ -234,7 +234,7 @@ bool P_MorphMonster (AActor *actor, const PClass *spawntype) } morphed = static_cast(Spawn (spawntype, actor->x, actor->y, actor->z, NO_REPLACE)); - DObject::PointerSubstitution (actor, morphed); + DObject::StaticPointerSubstitution (actor, morphed); morphed->tid = actor->tid; morphed->angle = actor->angle; morphed->UnmorphedMe = actor; @@ -311,7 +311,7 @@ bool P_UpdateMorphedMonster (AMorphedMonster *beast) memcpy (actor->args, beast->args, sizeof(actor->args)); actor->AddToHash (); beast->UnmorphedMe = NULL; - DObject::PointerSubstitution (beast, actor); + DObject::StaticPointerSubstitution (beast, actor); beast->Destroy (); Spawn (beast->x, beast->y, beast->z + TELEFOGHEIGHT, ALLOW_REPLACE); return true; diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index fbab89e6f..9bf9f8533 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -3671,7 +3671,7 @@ void P_SpawnPlayer (mapthing2_t *mthing, bool tempplayer) } - DObject::PointerSubstitution (oldactor, p->mo); + DObject::StaticPointerSubstitution (oldactor, p->mo); // PointerSubstitution() will also affect the bodyque, so undo that now. for (int ii=0; ii < BODYQUESIZE; ++ii) if (bodyque[ii] == p->mo)