diff --git a/source/core/coreactor.h b/source/core/coreactor.h index 0c79fdb3e..8ea67bcb0 100644 --- a/source/core/coreactor.h +++ b/source/core/coreactor.h @@ -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; -// 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); diff --git a/source/core/savegamehelp.cpp b/source/core/savegamehelp.cpp index 6984f4398..d32ce0649 100644 --- a/source/core/savegamehelp.cpp +++ b/source/core/savegamehelp.cpp @@ -75,7 +75,6 @@ extern FString BackupSaveGame; int SaveVersion; void SerializeMap(FSerializer &arc); -FixedBitArray 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 activeSprites; - // Savegame utilities class FileReader; extern int SaveVersion; diff --git a/source/games/blood/src/bloodactor.h b/source/games/blood/src/bloodactor.h index aec34bc21..9ad8aa05e 100644 --- a/source/games/blood/src/bloodactor.h +++ b/source/games/blood/src/bloodactor.h @@ -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() diff --git a/source/games/blood/src/loadsave.cpp b/source/games/blood/src/loadsave.cpp index 3cc5f96fd..5d7bb9d71 100644 --- a/source/games/blood/src/loadsave.cpp +++ b/source/games/blood/src/loadsave.cpp @@ -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(); } diff --git a/source/games/duke/src/savegame.cpp b/source/games/duke/src/savegame.cpp index b1c9fe308..cbb8e8833 100644 --- a/source/games/duke/src/savegame.cpp +++ b/source/games/duke/src/savegame.cpp @@ -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) diff --git a/source/games/duke/src/types.h b/source/games/duke/src/types.h index 7010e0696..761b5b634 100644 --- a/source/games/duke/src/types.h +++ b/source/games/duke/src/types.h @@ -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; } diff --git a/source/games/exhumed/src/exhumed.cpp b/source/games/exhumed/src/exhumed.cpp index 5109044d8..e1c74ee61 100644 --- a/source/games/exhumed/src/exhumed.cpp +++ b/source/games/exhumed/src/exhumed.cpp @@ -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(); } } diff --git a/source/games/exhumed/src/exhumedactor.h b/source/games/exhumed/src/exhumedactor.h index 66d364fce..6395cf406 100644 --- a/source/games/exhumed/src/exhumedactor.h +++ b/source/games/exhumed/src/exhumedactor.h @@ -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]; diff --git a/source/games/sw/src/save.cpp b/source/games/sw/src/save.cpp index 6dc57ac8f..a3516098a 100644 --- a/source/games/sw/src/save.cpp +++ b/source/games/sw/src/save.cpp @@ -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) diff --git a/source/games/sw/src/swactor.h b/source/games/sw/src/swactor.h index 2c4bda63f..9240bb72e 100644 --- a/source/games/sw/src/swactor.h +++ b/source/games/sw/src/swactor.h @@ -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];