- removed the old actor savegame code and instead implemented a virtual Serialize function.

This isn't hooked up yet, currently savegames are non-functional. They will come back once the global actor arrays are no longer relevant for maintenance.
This commit is contained in:
Christoph Oelckers 2021-12-05 09:20:41 +01:00
parent e79cd8d87f
commit 4cecb6f955
11 changed files with 101 additions and 127 deletions

View file

@ -17,6 +17,9 @@ public:
DCoreActor* prevStat, * nextStat;
DCoreActor* prevSect, * nextSect;
virtual ~DCoreActor() = default;
virtual void Serialize(FSerializer& arc);
bool exists() const
{
return (unsigned)s().statnum < MAXSTATUS;
@ -322,10 +325,6 @@ public:
using CoreSectIterator = TSectIterator<DCoreActor>;
// Only to be used by initial actor spawns!
void InsertActorSect(DCoreActor* actor, sectortype* sector, bool tail = false);
void InsertActorStat(DCoreActor* actor, int stat, bool tail = false);
DCoreActor* InsertActor(sectortype* sector, int stat, bool forcetail = false);
int DeleteActor(DCoreActor* actor);
void ChangeActorSect(DCoreActor* actor, sectortype* sector, bool forcetail = false);

View file

@ -75,7 +75,6 @@ extern FString BackupSaveGame;
int SaveVersion;
void SerializeMap(FSerializer &arc);
FixedBitArray<MAXSPRITES> activeSprites;
CVAR(String, cl_savedir, "", CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
@ -653,33 +652,17 @@ FSerializer &Serialize(FSerializer &arc, const char *key, walltype &c, walltype
}
void DCoreActor::Serialize(FSerializer& arc)
{
// nothing here yet.
}
void SerializeMap(FSerializer& arc)
{
// create a map of all used sprites so that we can use that elsewhere to only save what's needed.
activeSprites.Zero();
if (arc.isWriting())
{
for (int i=0; i<MAXSPRITES;i++)
{
if (sprite[i].statnum != MAXSTATUS)
{
activeSprites.Set(i);
}
}
}
else
{
memset(sprite, 0, sizeof(sprite[0]) * MAXSPRITES);
InitSpriteLists();
zsp = sprite[0];
}
if (arc.BeginObject("engine"))
{
arc.SerializeMemory("activesprites", activeSprites.Storage(), activeSprites.StorageSize())
.SparseArray("sprites", sprite, MAXSPRITES, activeSprites)
.SparseArray("spriteext", spriteext, MAXSPRITES, activeSprites)
("numsectors", numsectors)
arc("numsectors", numsectors)
("sectors", sector, sectorbackup)
("numwalls", numwalls)
("walls", wall, wallbackup)

View file

@ -5,8 +5,6 @@
#include "gamefuncs.h"
#include "coreactor.h"
extern FixedBitArray<MAXSPRITES> activeSprites;
// Savegame utilities
class FileReader;
extern int SaveVersion;

View file

@ -13,6 +13,7 @@ struct SPRITEHIT
class DBloodActor : public DCoreActor
{
using Super = DCoreActor;
DBloodActor* base();
public:
@ -39,6 +40,8 @@ public:
index = (int(this - base()));
}
void Serialize(FSerializer& arc) override;
DBloodActor& operator=(const DBloodActor& other) = default;
void Clear()

View file

@ -464,52 +464,41 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, DBloodActor*& w, D
return arc;
}
FSerializer& Serialize(FSerializer& arc, const char* keyname, DBloodActor& w, DBloodActor* def)
void DBloodActor::Serialize(FSerializer& arc)
{
static DBloodActor nul;
if (!def)
{
def = &nul;
if (arc.isReading()) w.Clear();
}
if (arc.BeginObject(keyname))
{
arc("xvel", w.xvel, def->xvel)
("yvel", w.yvel, def->yvel)
("zvel", w.zvel, def->zvel)
("hasx", w.hasx, def->hasx);
Super::Serialize(arc);
arc("xvel", xvel)
("yvel", yvel)
("zvel", zvel)
("hasx", hasx);
// The rest is only relevant if the actor has an xsprite.
if (w.hasX())
if (hasX())
{
arc("xsprite", w.xsprite, def->xsprite)
("dudeslope", w.dudeSlope, def->dudeSlope)
("dudeextra", w.dudeExtra, def->dudeExtra)
("explosionflag", w.explosionhackflag, def->explosionhackflag)
("spritehit", w.hit, def->hit)
("basepoint", w.basePoint, def->basePoint)
("owneractor", w.ownerActor, def->ownerActor);
arc("xsprite", xsprite)
("dudeslope", dudeSlope)
("dudeextra", dudeExtra)
("explosionflag", explosionhackflag)
("spritehit", hit)
("basepoint", basePoint)
("owneractor", ownerActor);
#ifdef NOONE_EXTENSIONS
if (gModernMap)
{
arc("spritemass", w.spriteMass, def->spriteMass) // no treatment for old savegames. If this gets lost it is not critical
("prevmarker", w.prevmarker, def->prevmarker)
.Array("conditions", w.condition, def->condition, 2);
arc("spritemass", spriteMass)
("prevmarker", prevmarker)
.Array("conditions", condition, 2);
// GenDudeExtra only contains valid info for kDudeModernCustom and kDudeModernCustomBurning so only save when needed as these are not small.
if (w.s().type == kDudeModernCustom || w.s().type == kDudeModernCustomBurning)
if (s().type == kDudeModernCustom || s().type == kDudeModernCustomBurning)
{
arc("gendudeextra", w.genDudeExtra);
arc("gendudeextra", genDudeExtra);
}
}
#endif
}
arc.EndObject();
}
return arc;
}
FSerializer& Serialize(FSerializer& arc, const char* keyname, XWALL& w, XWALL* def)
@ -692,9 +681,7 @@ void SerializeState(FSerializer& arc)
("scale", pSky->yscale)
.Array("tileofs", pSky->tileofs, countof(pSky->tileofs))
("numtiles", pSky->lognumtiles)
("gameoptions", gGameOptions)
.SparseArray("actors", bloodActors, kMaxSprites, activeSprites);
("gameoptions", gGameOptions);
arc.EndObject();
}

View file

@ -283,39 +283,38 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, player_struct& w,
}
FSerializer& Serialize(FSerializer& arc, const char* keyname, DDukeActor& w, DDukeActor* def)
void DDukeActor::Serialize(FSerializer& arc)
{
if (!def) def = &hittype[MAXSPRITES];
if (arc.BeginObject(keyname))
{
arc("cgg", w.cgg, def->cgg)
("spriteextra", w.spriteextra, def->spriteextra)
("picnum", w.picnum, def->picnum)
("ang", w.ang, def->ang)
("extra", w.extra, def->extra)
("owneractor", w.ownerActor, def->ownerActor)
("owner", w.hitOwnerActor, def->hitOwnerActor)
("movflag", w.movflag, def->movflag)
("tempang", w.tempang, def->tempang)
("actorstayput", w.actorstayput, def->actorstayput)
("dispicnum", w.dispicnum, def->dispicnum)
("timetosleep", w.timetosleep, def->timetosleep)
("floorz", w.floorz, def->floorz)
("ceilingz", w.ceilingz, def->ceilingz)
("lastvx", w.lastvx, def->lastvx)
("lastvy", w.lastvy, def->lastvy)
("aflags", w.aflags, def->aflags)
("saved_ammo", w.saved_ammo, def->saved_ammo)
("temp_actor", w.temp_actor, def->temp_actor)
("seek_actor", w.seek_actor, def->seek_actor)
.Array("temp_data", w.temp_data, def->temp_data, 6)
.Array("temo_wall", w.temp_walls, def->temp_walls,2)
("temp_sect", w.temp_sect, def->temp_sect)
.EndObject();
}
return arc;
//AActor* def = GetDefault();
Super::Serialize(arc);
arc("cgg", cgg)
("spriteextra", spriteextra)
("picnum", picnum)
("ang", ang)
("extra", extra)
("owneractor", ownerActor)
("owner", hitOwnerActor)
("movflag", movflag)
("tempang", tempang)
("actorstayput", actorstayput)
("dispicnum", dispicnum)
("timetosleep", timetosleep)
("floorz", floorz)
("ceilingz", ceilingz)
("lastvx", lastvx)
("lastvy", lastvy)
("aflags", aflags)
("saved_ammo", saved_ammo)
("temp_actor", temp_actor)
("seek_actor", seek_actor)
.Array("temp_data", temp_data, 6)
.Array("temo_wall", temp_walls, 2)
("temp_sect", temp_sect);
}
FSerializer& Serialize(FSerializer& arc, const char* keyname, Cycler& w, Cycler* def)
{
static Cycler nul;
@ -348,8 +347,7 @@ void GameInterface::SerializeGameState(FSerializer& arc)
{
arc("multimode", ud.multimode);
arc.SparseArray("actors", hittype, MAXSPRITES, activeSprites)
("skill", ud.player_skill)
arc("skill", ud.player_skill)
("from_bonus", ud.from_bonus)
("secretlevel", ud.secretlevel)
("respawn_monsters", ud.respawn_monsters)

View file

@ -23,6 +23,8 @@ struct STATUSBARTYPE
struct DDukeActor : public DCoreActor
{
using Super = DCoreActor;
uint8_t cgg;
uint8_t spriteextra; // moved here for easier maintenance. This was originally a hacked in field in the sprite structure called 'filler'.
DDukeActor* ownerActor, * hitOwnerActor;
@ -99,6 +101,9 @@ struct DDukeActor : public DCoreActor
// only valid for real players - just here to abstract yvel.
return s->yvel;
}
void Serialize(FSerializer& arc) override;
};
extern DDukeActor hittype[MAXSPRITES + 1];
inline DDukeActor* DDukeActor::array() { return hittype; }

View file

@ -570,28 +570,24 @@ bool GameInterface::CanSave()
return new GameInterface;
}
FSerializer& Serialize(FSerializer& arc, const char* keyname, DExhumedActor& w, DExhumedActor* def)
void DExhumedActor::Serialize(FSerializer& arc)
{
if (arc.BeginObject(keyname))
{
arc("phase", w.nPhase)
("health", w.nHealth)
("frame", w.nFrame)
("action", w.nAction)
("target", w.pTarget)
("count", w.nCount)
("run", w.nRun)
("index", w.nIndex)
("index2", w.nIndex2)
("channel", w.nChannel)
("damage", w.nDamage)
Super::Serialize(arc);
arc("phase", nPhase)
("health", nHealth)
("frame", nFrame)
("action", nAction)
("target", pTarget)
("count", nCount)
("run", nRun)
("index", nIndex)
("index2", nIndex2)
("channel", nChannel)
("damage", nDamage)
("turn", w.nTurn)
("x", w.x)
("y", w.y)
.EndObject();
}
return arc;
("turn", nTurn)
("x", x)
("y", y);
}
void SerializeState(FSerializer& arc)
@ -622,7 +618,6 @@ void SerializeState(FSerializer& arc)
("slipmode", bSlipMode)
("PlayClock", PlayClock)
("spiritsprite", pSpiritSprite)
.SparseArray("actors", exhumedActors, kMaxSprites, activeSprites)
.EndObject();
}
}

View file

@ -16,6 +16,8 @@ enum
class DExhumedActor : public DCoreActor
{
using Super = DCoreActor;
DExhumedActor* base();
public:
@ -48,6 +50,9 @@ public:
void Clear()
{
}
void Serialize(FSerializer& arc) override;
};
extern DExhumedActor exhumedActors[MAXSPRITES];

View file

@ -1109,19 +1109,16 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, TRACK& w, TRACK* d
//
//---------------------------------------------------------------------------
FSerializer& Serialize(FSerializer& arc, const char* keyname, DSWActor& w, DSWActor* def)
void DSWActor::Serialize(FSerializer& arc)
{
Super::Serialize(arc);
if (arc.isReading())
{
w.Clear();
// nuke the User before loading anything.
Clear();
}
if (arc.BeginObject(keyname))
{
arc("hasuser", w.hasUser);
if (w.hasUser) arc("user", w.user); // only write if defined.
arc.EndObject();
}
return arc;
arc("hasuser", hasUser);
if (hasUser) arc("user", user); // only write if defined.
}
//---------------------------------------------------------------------------
@ -1139,8 +1136,7 @@ void GameInterface::SerializeGameState(FSerializer& arc)
{
preSerializePanelSprites(arc);
so_serializeinterpolations(arc);
arc .SparseArray("actors", swActors, MAXSPRITES, activeSprites)
("numplayers", numplayers)
arc ("numplayers", numplayers)
.Array("players", Player, numplayers)
("skill", Skill)
("screenpeek", screenpeek)

View file

@ -7,6 +7,8 @@ BEGIN_SW_NS
class DSWActor : public DCoreActor
{
using Super = DCoreActor;
DSWActor* base();
public:
@ -40,6 +42,9 @@ public:
hasUser = false;
user.Clear();
}
void Serialize(FSerializer& arc) override;
};
extern DSWActor swActors[MAXSPRITES];