- fixed: Decals may not be serialized before thinkers.

Since decals may have thinkers attached this will crash when such a savegame gets loaded, because the thinker lists get reset in P_SerializeThinkers, deleting any thinker that already was processed.
I also added an error message that immediately aborts the save process if such an out-of-sequence thinker is attempted to be written out.
This obviously breaks savegame compatibility again...
This commit is contained in:
Christoph Oelckers 2016-04-29 11:44:17 +02:00
parent f3d273c94f
commit 4a72c7d2f1
6 changed files with 35 additions and 7 deletions

View file

@ -1054,6 +1054,12 @@ FArchive &FArchive::SerializePointer (void *ptrbase, BYTE **ptr, DWORD elemSize)
FArchive &FArchive::SerializeObject (DObject *&object, PClass *type) FArchive &FArchive::SerializeObject (DObject *&object, PClass *type)
{ {
if (!m_ThinkersAllowed && type->IsDescendantOf(RUNTIME_CLASS(DThinker)))
{
assert(true);
I_Error("Tried to serialize a thinker before P_SerializeThinkers");
}
if (!type->IsDescendantOf(RUNTIME_CLASS(PClass))) if (!type->IsDescendantOf(RUNTIME_CLASS(PClass)))
{ // a regular object { // a regular object
if (IsStoring()) if (IsStoring())

View file

@ -216,6 +216,16 @@ inline FArchive& operator<< (signed char *&str) { return operator<< ((char *&)st
inline FArchive& operator<< (bool &b) { return operator<< ((BYTE &)b); } inline FArchive& operator<< (bool &b) { return operator<< ((BYTE &)b); }
inline FArchive& operator<< (DObject* &object) { return ReadObject (object, RUNTIME_CLASS(DObject)); } inline FArchive& operator<< (DObject* &object) { return ReadObject (object, RUNTIME_CLASS(DObject)); }
void EnableThinkers()
{
m_ThinkersAllowed = true;
}
bool ThinkersAllowed()
{
return m_ThinkersAllowed;
}
protected: protected:
enum { EObjectHashSize = 137 }; enum { EObjectHashSize = 137 };
@ -253,6 +263,7 @@ protected:
int *m_SpriteMap; int *m_SpriteMap;
size_t m_NumSprites; size_t m_NumSprites;
bool m_ThinkersAllowed = false;
FArchive (); FArchive ();
void AttachToFile (FFile &file); void AttachToFile (FFile &file);

View file

@ -72,10 +72,7 @@ void DEarthquake::Serialize (FArchive &arc)
<< m_QuakeSFX << m_Flags << m_CountdownStart << m_QuakeSFX << m_Flags << m_CountdownStart
<< m_WaveSpeed << m_WaveSpeed
<< m_Falloff << m_Highpoint << m_MiniCount; << m_Falloff << m_Highpoint << m_MiniCount;
if (SaveVersion >= 4544) << m_RollIntensity << m_RollWave;
{
arc << m_RollIntensity << m_RollWave;
}
} }
//========================================================================== //==========================================================================

View file

@ -423,7 +423,6 @@ void P_SerializeWorld (FArchive &arc)
<< si->LeftSide << si->LeftSide
<< si->RightSide << si->RightSide
<< si->Index; << si->Index;
DBaseDecal::SerializeChain (arc, &si->AttachedDecals);
} }
} }
@ -452,6 +451,7 @@ void P_SerializeWorldActors(FArchive &arc)
{ {
int i; int i;
sector_t *sec; sector_t *sec;
line_t *line;
for (i = 0, sec = sectors; i < numsectors; i++, sec++) for (i = 0, sec = sectors; i < numsectors; i++, sec++)
{ {
@ -465,6 +465,16 @@ void P_SerializeWorldActors(FArchive &arc)
{ {
arc << s.mSkybox; arc << s.mSkybox;
} }
for (i = 0, line = lines; i < numlines; i++, line++)
{
for (int s = 0; s < 2; s++)
{
if (line->sidedef[s] != NULL)
{
DBaseDecal::SerializeChain(arc, &line->sidedef[s]->AttachedDecals);
}
}
}
} }
void extsector_t::Serialize(FArchive &arc) void extsector_t::Serialize(FArchive &arc)
@ -504,6 +514,7 @@ FArchive &operator<< (FArchive &arc, sector_t::splane &p)
void P_SerializeThinkers (FArchive &arc, bool hubLoad) void P_SerializeThinkers (FArchive &arc, bool hubLoad)
{ {
arc.EnableThinkers();
DImpactDecal::SerializeTime (arc); DImpactDecal::SerializeTime (arc);
DThinker::SerializeAll (arc, hubLoad); DThinker::SerializeAll (arc, hubLoad);
} }

View file

@ -72,11 +72,11 @@ const char *GetVersionString();
// SAVESIG should match SAVEVER. // SAVESIG should match SAVEVER.
// MINSAVEVER is the minimum level snapshot version that can be loaded. // MINSAVEVER is the minimum level snapshot version that can be loaded.
#define MINSAVEVER 4543 #define MINSAVEVER 4545
// Use 4500 as the base git save version, since it's higher than the // Use 4500 as the base git save version, since it's higher than the
// SVN revision ever got. // SVN revision ever got.
#define SAVEVER 4544 #define SAVEVER 4545
#define SAVEVERSTRINGIFY2(x) #x #define SAVEVERSTRINGIFY2(x) #x
#define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x) #define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x)

View file

@ -231,3 +231,6 @@ enum
444 = 0, Teleport(0) 444 = 0, Teleport(0)
445 = 0, Teleport_NoFog(0) 445 = 0, Teleport_NoFog(0)
446 = 0, Teleport_Line(0) 446 = 0, Teleport_Line(0)
447 = 0, Exit_Normal(0)
448 = 0, Exit_Secret(0)
449 = 0, Teleport_NewMap(0)