mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 14:51:51 +00:00
- added the last missing bits of the savegame code - thinker list deserialization and handling of players during hub travel. Now testing is what remains...
This commit is contained in:
parent
edb7f7959e
commit
01d28e3eb2
6 changed files with 130 additions and 63 deletions
|
@ -1001,7 +1001,6 @@ set( FASTMATH_SOURCES
|
|||
)
|
||||
|
||||
set (PCH_SOURCES
|
||||
json.cpp
|
||||
actorptrselect.cpp
|
||||
am_map.cpp
|
||||
b_bot.cpp
|
||||
|
|
|
@ -116,6 +116,85 @@ void DThinker::SaveList(FSerializer &arc, DThinker *node)
|
|||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void DThinker::SerializeThinkers(FSerializer &arc, bool hubLoad)
|
||||
{
|
||||
//DThinker *thinker;
|
||||
//BYTE stat;
|
||||
//int statcount;
|
||||
int i;
|
||||
|
||||
if (arc.isWriting())
|
||||
{
|
||||
arc.BeginArray("thinkers");
|
||||
for (i = 0; i <= MAX_STATNUM; i++)
|
||||
{
|
||||
arc.BeginArray(nullptr);
|
||||
SaveList(arc, Thinkers[i].GetHead());
|
||||
SaveList(arc, FreshThinkers[i].GetHead());
|
||||
arc.EndArray();
|
||||
}
|
||||
arc.EndArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (arc.BeginArray("thinkers"))
|
||||
{
|
||||
for (i = 0; i <= MAX_STATNUM; i++)
|
||||
{
|
||||
if (arc.BeginArray(nullptr))
|
||||
{
|
||||
int size = arc.ArraySize();
|
||||
for (int j = 0; j < size; j++)
|
||||
{
|
||||
DThinker *thinker;
|
||||
arc(nullptr, thinker);
|
||||
if (thinker != nullptr)
|
||||
{
|
||||
// This may be a player stored in their ancillary list. Remove
|
||||
// them first before inserting them into the new list.
|
||||
if (thinker->NextThinker != nullptr)
|
||||
{
|
||||
thinker->Remove();
|
||||
}
|
||||
// Thinkers with the OF_JustSpawned flag set go in the FreshThinkers
|
||||
// list. Anything else goes in the regular Thinkers list.
|
||||
if (thinker->ObjectFlags & OF_EuthanizeMe)
|
||||
{
|
||||
// This thinker was destroyed during the loading process. Do
|
||||
// not link it into any list.
|
||||
}
|
||||
else if (thinker->ObjectFlags & OF_JustSpawned)
|
||||
{
|
||||
FreshThinkers[i].AddTail(thinker);
|
||||
thinker->PostSerialize();
|
||||
}
|
||||
else
|
||||
{
|
||||
Thinkers[i].AddTail(thinker);
|
||||
thinker->PostSerialize();
|
||||
}
|
||||
}
|
||||
}
|
||||
arc.EndArray();
|
||||
}
|
||||
}
|
||||
arc.EndArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
DThinker::DThinker (int statnum) throw()
|
||||
{
|
||||
NextThinker = NULL;
|
||||
|
|
39
src/json.cpp
39
src/json.cpp
|
@ -1,39 +0,0 @@
|
|||
#include "serializer.h"
|
||||
#include "r_local.h"
|
||||
#include "p_setup.h"
|
||||
#include "c_dispatch.h"
|
||||
#include "i_system.h"
|
||||
#include "a_sharedglobal.h"
|
||||
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
|
||||
void DThinker::SerializeThinkers(FSerializer &arc, bool hubLoad)
|
||||
{
|
||||
//DThinker *thinker;
|
||||
//BYTE stat;
|
||||
//int statcount;
|
||||
int i;
|
||||
|
||||
if (arc.isWriting())
|
||||
{
|
||||
arc.BeginArray("thinkers");
|
||||
for (i = 0; i <= MAX_STATNUM; i++)
|
||||
{
|
||||
arc.BeginArray(nullptr);
|
||||
SaveList(arc, Thinkers[i].GetHead());
|
||||
SaveList(arc, FreshThinkers[i].GetHead());
|
||||
arc.EndArray();
|
||||
}
|
||||
arc.EndArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
|
@ -63,10 +63,6 @@
|
|||
#include "r_renderer.h"
|
||||
#include "serializer.h"
|
||||
|
||||
// just the stuff that already got converted to FSerializer so that it can be seen as 'done' when searching.
|
||||
#include "zzz_old.cpp"
|
||||
|
||||
|
||||
//
|
||||
// Thinkers
|
||||
//
|
||||
|
@ -905,7 +901,7 @@ void G_SerializeLevel(FSerializer &arc, bool hubload)
|
|||
{
|
||||
P_DestroyThinkers(hubload);
|
||||
interpolator.ClearInterpolations();
|
||||
arc.ReadObjects();
|
||||
arc.ReadObjects(hubload);
|
||||
}
|
||||
|
||||
arc("level.flags", level.flags)
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "v_text.h"
|
||||
|
||||
char nulspace[1024 * 1024 * 4];
|
||||
bool save_full = false; // for testing. Should be removed afterward.
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -206,7 +207,7 @@ struct FReader
|
|||
rapidjson::Document doc;
|
||||
mDoc.Parse(buffer, length);
|
||||
mObjects.Push(FJSONObject(&mDoc));
|
||||
memset(mPlayers, 0, sizeof(mPlayers));
|
||||
memset(mPlayers, -1, sizeof(mPlayers));
|
||||
}
|
||||
|
||||
rapidjson::Value *FindKey(const char *key)
|
||||
|
@ -806,7 +807,7 @@ void FSerializer::WriteObjects()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FSerializer::ReadObjects()
|
||||
void FSerializer::ReadObjects(bool hubtravel)
|
||||
{
|
||||
bool founderrors = false;
|
||||
|
||||
|
@ -823,6 +824,7 @@ void FSerializer::ReadObjects()
|
|||
if (BeginObject(nullptr))
|
||||
{
|
||||
FString clsname; // do not deserialize the class type directly so that we can print appropriate errors.
|
||||
int pindex = -1;
|
||||
|
||||
Serialize(*this, "classtype", clsname, nullptr);
|
||||
PClass *cls = PClass::FindClass(clsname);
|
||||
|
@ -830,6 +832,7 @@ void FSerializer::ReadObjects()
|
|||
{
|
||||
Printf("Unknown object class '%d' in savegame", clsname.GetChars());
|
||||
founderrors = true;
|
||||
r->mDObjects[i] = RUNTIME_CLASS(AActor)->CreateNew(); // make sure we got at least a valid pointer for the duration of the loading process.
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -849,33 +852,60 @@ void FSerializer::ReadObjects()
|
|||
for (unsigned i = 0; i < r->mDObjects.Size(); i++)
|
||||
{
|
||||
auto obj = r->mDObjects[i];
|
||||
try
|
||||
{
|
||||
if (BeginObject(nullptr))
|
||||
{
|
||||
int pindex = -1;
|
||||
Serialize(*this, "playerindex", pindex, nullptr);
|
||||
if (obj != nullptr)
|
||||
{
|
||||
if (pindex >= 0 && pindex < MAXPLAYERS)
|
||||
int pindex = -1;
|
||||
if (hubtravel)
|
||||
{
|
||||
// mark this as a hub travelling player. This needs to be taken care of later and be replaced with the real travelling player,
|
||||
// but that's better done at the end of this loop so that inventory ownership is not getting messed up.
|
||||
Serialize(*this, "playerindex", pindex, nullptr);
|
||||
if (hubtravel && pindex >= 0 && pindex < MAXPLAYERS)
|
||||
{
|
||||
obj->ObjectFlags |= OF_LoadedPlayer;
|
||||
r->mPlayers[pindex] = int(i);
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
obj->SerializeUserVars(*this);
|
||||
obj->Serialize(*this);
|
||||
}
|
||||
EndObject();
|
||||
}
|
||||
}
|
||||
catch (CRecoverableError &err)
|
||||
{
|
||||
// In case something in here throws an error, let's continue and deal with it later.
|
||||
Printf(TEXTCOLOR_RED "'%s'\n while restoring %s", err.GetMessage(), obj ? obj->GetClass()->TypeName.GetChars() : "invalid object");
|
||||
mErrors++;
|
||||
}
|
||||
}
|
||||
EndObject();
|
||||
}
|
||||
}
|
||||
}
|
||||
EndArray();
|
||||
|
||||
if (hubtravel)
|
||||
{
|
||||
for (int i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
int pindex = r->mPlayers[i];
|
||||
if (pindex != -1)
|
||||
{
|
||||
if (players[i].mo != nullptr)
|
||||
{
|
||||
r->mDObjects[pindex]->Destroy();
|
||||
DObject::StaticPointerSubstitution(r->mDObjects[pindex], players[i].mo);
|
||||
r->mDObjects[pindex] = players[i].mo;
|
||||
}
|
||||
else
|
||||
{
|
||||
players[i].mo = static_cast<APlayerPawn*>(r->mDObjects[pindex]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DThinker::bSerialOverride = false;
|
||||
assert(!founderrors);
|
||||
if (founderrors)
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#include "r_defs.h"
|
||||
#include "resourcefiles/file_zip.h"
|
||||
|
||||
extern bool save_full;
|
||||
|
||||
struct ticcmd_t;
|
||||
struct usercmd_t;
|
||||
|
||||
|
@ -72,7 +74,7 @@ public:
|
|||
bool OpenReader(const char *buffer, size_t length);
|
||||
bool OpenReader(FCompressedBuffer *input);
|
||||
void Close();
|
||||
void ReadObjects();
|
||||
void ReadObjects(bool hubtravel);
|
||||
bool BeginObject(const char *name);
|
||||
void EndObject();
|
||||
bool BeginArray(const char *name);
|
||||
|
@ -108,13 +110,13 @@ public:
|
|||
template<class T>
|
||||
FSerializer &operator()(const char *key, T &obj, T &def)
|
||||
{
|
||||
return Serialize(*this, key, obj, &def);
|
||||
return Serialize(*this, key, obj, save_full? nullptr : &def);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
FSerializer &Array(const char *key, T *obj, int count, bool fullcompare = false)
|
||||
{
|
||||
if (fullcompare && isWriting() && nullcmp(obj, count * sizeof(T)))
|
||||
if (!save_full && fullcompare && isWriting() && nullcmp(obj, count * sizeof(T)))
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
@ -138,7 +140,7 @@ public:
|
|||
template<class T>
|
||||
FSerializer &Array(const char *key, T *obj, T *def, int count, bool fullcompare = false)
|
||||
{
|
||||
if (fullcompare && isWriting() && def != nullptr && !memcmp(obj, def, count * sizeof(T)))
|
||||
if (!save_full && fullcompare && isWriting() && def != nullptr && !memcmp(obj, def, count * sizeof(T)))
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue