mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-14 08:31:23 +00:00
- moved new code to its proper location and started moving the replaced old archive code to a placeholder file for easy removal later.
This commit is contained in:
parent
65c6388d44
commit
c665cc53f9
13 changed files with 1431 additions and 1293 deletions
|
@ -585,6 +585,7 @@ public:
|
||||||
|
|
||||||
void Serialize (FArchive &arc);
|
void Serialize (FArchive &arc);
|
||||||
void Serialize(FSerializer &arc);
|
void Serialize(FSerializer &arc);
|
||||||
|
void PostSerialize();
|
||||||
|
|
||||||
static AActor *StaticSpawn (PClassActor *type, const DVector3 &pos, replace_t allowreplacement, bool SpawningMapThing = false);
|
static AActor *StaticSpawn (PClassActor *type, const DVector3 &pos, replace_t allowreplacement, bool SpawningMapThing = false);
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
#include "a_sharedglobal.h"
|
#include "a_sharedglobal.h"
|
||||||
#include "dsectoreffect.h"
|
#include "dsectoreffect.h"
|
||||||
#include "farchive.h"
|
#include "farchive.h"
|
||||||
|
#include "serializer.h"
|
||||||
|
|
||||||
ClassReg DObject::RegistrationInfo =
|
ClassReg DObject::RegistrationInfo =
|
||||||
{
|
{
|
||||||
|
@ -479,7 +480,7 @@ void DObject::SerializeUserVars(FArchive &arc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DObject::Serialize (FArchive &arc)
|
void DObject::Serialize(FSerializer &arc)
|
||||||
{
|
{
|
||||||
ObjectFlags |= OF_SerialSuccess;
|
ObjectFlags |= OF_SerialSuccess;
|
||||||
}
|
}
|
||||||
|
|
|
@ -261,6 +261,10 @@ void DThinker::PostBeginPlay ()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DThinker::PostSerialize()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
DThinker *DThinker::FirstThinker (int statnum)
|
DThinker *DThinker::FirstThinker (int statnum)
|
||||||
{
|
{
|
||||||
DThinker *node;
|
DThinker *node;
|
||||||
|
|
|
@ -70,6 +70,7 @@ public:
|
||||||
virtual ~DThinker ();
|
virtual ~DThinker ();
|
||||||
virtual void Tick ();
|
virtual void Tick ();
|
||||||
virtual void PostBeginPlay (); // Called just before the first tick
|
virtual void PostBeginPlay (); // Called just before the first tick
|
||||||
|
virtual void PostSerialize();
|
||||||
size_t PropagateMark();
|
size_t PropagateMark();
|
||||||
|
|
||||||
void ChangeStatNum (int statnum);
|
void ChangeStatNum (int statnum);
|
||||||
|
|
145
src/farchive.cpp
145
src/farchive.cpp
|
@ -1085,109 +1085,6 @@ FArchive &FArchive::SerializeObject (DObject *&object, PClass *type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FArchive &FArchive::WriteObject (DObject *obj)
|
|
||||||
{
|
|
||||||
player_t *player;
|
|
||||||
BYTE id[2];
|
|
||||||
|
|
||||||
if (obj == NULL)
|
|
||||||
{
|
|
||||||
id[0] = NULL_OBJ;
|
|
||||||
Write (id, 1);
|
|
||||||
}
|
|
||||||
else if (obj == (DObject*)~0)
|
|
||||||
{
|
|
||||||
id[0] = M1_OBJ;
|
|
||||||
Write (id, 1);
|
|
||||||
}
|
|
||||||
else if (obj->ObjectFlags & OF_EuthanizeMe)
|
|
||||||
{
|
|
||||||
// Objects that want to die are not saved to the archive, but
|
|
||||||
// we leave the pointers to them alone.
|
|
||||||
id[0] = NULL_OBJ;
|
|
||||||
Write (id, 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PClass *type = obj->GetClass();
|
|
||||||
DWORD *classarcid;
|
|
||||||
|
|
||||||
if (type == RUNTIME_CLASS(DObject))
|
|
||||||
{
|
|
||||||
//I_Error ("Tried to save an instance of DObject.\n"
|
|
||||||
// "This should not happen.\n");
|
|
||||||
id[0] = NULL_OBJ;
|
|
||||||
Write (id, 1);
|
|
||||||
}
|
|
||||||
else if (NULL == (classarcid = ClassToArchive.CheckKey(type)))
|
|
||||||
{
|
|
||||||
// No instances of this class have been written out yet.
|
|
||||||
// Write out the class, then write out the object. If this
|
|
||||||
// is an actor controlled by a player, make note of that
|
|
||||||
// so that it can be overridden when moving around in a hub.
|
|
||||||
if (obj->IsKindOf (RUNTIME_CLASS (AActor)) &&
|
|
||||||
(player = static_cast<AActor *>(obj)->player) &&
|
|
||||||
player->mo == obj)
|
|
||||||
{
|
|
||||||
id[0] = NEW_PLYR_CLS_OBJ;
|
|
||||||
id[1] = (BYTE)(player - players);
|
|
||||||
Write (id, 2);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
id[0] = NEW_CLS_OBJ;
|
|
||||||
Write (id, 1);
|
|
||||||
}
|
|
||||||
WriteClass (type);
|
|
||||||
// Printf ("Make class %s (%u)\n", type->Name, m_File->Tell());
|
|
||||||
MapObject (obj);
|
|
||||||
obj->SerializeUserVars (*this);
|
|
||||||
obj->Serialize (*this);
|
|
||||||
obj->CheckIfSerialized ();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// An instance of this class has already been saved. If
|
|
||||||
// this object has already been written, save a reference
|
|
||||||
// to the saved object. Otherwise, save a reference to the
|
|
||||||
// class, then save the object. Again, if this is a player-
|
|
||||||
// controlled actor, remember that.
|
|
||||||
DWORD *objarcid = ObjectToArchive.CheckKey(obj);
|
|
||||||
|
|
||||||
if (objarcid == NULL)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (obj->IsKindOf (RUNTIME_CLASS (AActor)) &&
|
|
||||||
(player = static_cast<AActor *>(obj)->player) &&
|
|
||||||
player->mo == obj)
|
|
||||||
{
|
|
||||||
id[0] = NEW_PLYR_OBJ;
|
|
||||||
id[1] = (BYTE)(player - players);
|
|
||||||
Write (id, 2);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
id[0] = NEW_OBJ;
|
|
||||||
Write (id, 1);
|
|
||||||
}
|
|
||||||
WriteCount (*classarcid);
|
|
||||||
// Printf ("Reuse class %s (%u)\n", type->Name, m_File->Tell());
|
|
||||||
MapObject (obj);
|
|
||||||
obj->SerializeUserVars (*this);
|
|
||||||
obj->Serialize (*this);
|
|
||||||
obj->CheckIfSerialized ();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
id[0] = OLD_OBJ;
|
|
||||||
Write (id, 1);
|
|
||||||
WriteCount (*objarcid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
FArchive &FArchive::ReadObject (DObject* &obj, PClass *wanttype)
|
FArchive &FArchive::ReadObject (DObject* &obj, PClass *wanttype)
|
||||||
{
|
{
|
||||||
BYTE objHead;
|
BYTE objHead;
|
||||||
|
@ -1545,45 +1442,3 @@ void FArchive::UserReadClass (PClass *&type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FArchive &operator<< (FArchive &arc, sector_t *&sec)
|
|
||||||
{
|
|
||||||
return arc.SerializePointer (sectors, (BYTE **)&sec, sizeof(*sectors));
|
|
||||||
}
|
|
||||||
|
|
||||||
FArchive &operator<< (FArchive &arc, const sector_t *&sec)
|
|
||||||
{
|
|
||||||
return arc.SerializePointer (sectors, (BYTE **)&sec, sizeof(*sectors));
|
|
||||||
}
|
|
||||||
|
|
||||||
FArchive &operator<< (FArchive &arc, line_t *&line)
|
|
||||||
{
|
|
||||||
return arc.SerializePointer (lines, (BYTE **)&line, sizeof(*lines));
|
|
||||||
}
|
|
||||||
|
|
||||||
FArchive &operator<< (FArchive &arc, vertex_t *&vert)
|
|
||||||
{
|
|
||||||
return arc.SerializePointer (vertexes, (BYTE **)&vert, sizeof(*vertexes));
|
|
||||||
}
|
|
||||||
|
|
||||||
FArchive &operator<< (FArchive &arc, side_t *&side)
|
|
||||||
{
|
|
||||||
return arc.SerializePointer (sides, (BYTE **)&side, sizeof(*sides));
|
|
||||||
}
|
|
||||||
|
|
||||||
FArchive &operator<<(FArchive &arc, DAngle &ang)
|
|
||||||
{
|
|
||||||
arc << ang.Degrees;
|
|
||||||
return arc;
|
|
||||||
}
|
|
||||||
|
|
||||||
FArchive &operator<<(FArchive &arc, DVector3 &vec)
|
|
||||||
{
|
|
||||||
arc << vec.X << vec.Y << vec.Z;
|
|
||||||
return arc;
|
|
||||||
}
|
|
||||||
|
|
||||||
FArchive &operator<<(FArchive &arc, DVector2 &vec)
|
|
||||||
{
|
|
||||||
arc << vec.X << vec.Y;
|
|
||||||
return arc;
|
|
||||||
}
|
|
||||||
|
|
131
src/g_level.cpp
131
src/g_level.cpp
|
@ -1474,137 +1474,6 @@ void G_AirControlChanged ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void G_SerializeLevel (FArchive &arc, bool hubLoad)
|
|
||||||
{
|
|
||||||
int i = level.totaltime;
|
|
||||||
|
|
||||||
unsigned tm = I_MSTime();
|
|
||||||
|
|
||||||
Renderer->StartSerialize(arc);
|
|
||||||
if (arc.IsLoading()) P_DestroyThinkers(hubLoad);
|
|
||||||
|
|
||||||
arc << level.flags
|
|
||||||
<< level.flags2
|
|
||||||
<< level.fadeto
|
|
||||||
<< level.found_secrets
|
|
||||||
<< level.found_items
|
|
||||||
<< level.killed_monsters
|
|
||||||
<< level.gravity
|
|
||||||
<< level.aircontrol
|
|
||||||
<< level.teamdamage
|
|
||||||
<< level.maptime
|
|
||||||
<< i;
|
|
||||||
|
|
||||||
// Hub transitions must keep the current total time
|
|
||||||
if (!hubLoad)
|
|
||||||
level.totaltime = i;
|
|
||||||
|
|
||||||
arc << level.skytexture1 << level.skytexture2;
|
|
||||||
if (arc.IsLoading())
|
|
||||||
{
|
|
||||||
sky1texture = level.skytexture1;
|
|
||||||
sky2texture = level.skytexture2;
|
|
||||||
R_InitSkyMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
G_AirControlChanged ();
|
|
||||||
|
|
||||||
BYTE t;
|
|
||||||
|
|
||||||
// Does this level have scrollers?
|
|
||||||
if (arc.IsStoring ())
|
|
||||||
{
|
|
||||||
t = level.Scrolls ? 1 : 0;
|
|
||||||
arc << t;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
arc << t;
|
|
||||||
if (level.Scrolls)
|
|
||||||
{
|
|
||||||
delete[] level.Scrolls;
|
|
||||||
level.Scrolls = NULL;
|
|
||||||
}
|
|
||||||
if (t)
|
|
||||||
{
|
|
||||||
level.Scrolls = new FSectorScrollValues[numsectors];
|
|
||||||
memset (level.Scrolls, 0, sizeof(level.Scrolls)*numsectors);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FBehavior::StaticSerializeModuleStates (arc);
|
|
||||||
if (arc.IsLoading()) interpolator.ClearInterpolations();
|
|
||||||
P_SerializeWorld(arc);
|
|
||||||
P_SerializeThinkers (arc, hubLoad);
|
|
||||||
P_SerializeWorldActors(arc); // serializing actor pointers in the world data must be done after SerializeWorld has restored the entire sector state, otherwise LinkToWorld may fail.
|
|
||||||
P_SerializePolyobjs (arc);
|
|
||||||
P_SerializeSubsectors(arc);
|
|
||||||
StatusBar->Serialize (arc);
|
|
||||||
|
|
||||||
arc << level.total_monsters << level.total_items << level.total_secrets;
|
|
||||||
|
|
||||||
// Does this level have custom translations?
|
|
||||||
FRemapTable *trans;
|
|
||||||
WORD w;
|
|
||||||
if (arc.IsStoring ())
|
|
||||||
{
|
|
||||||
for (unsigned int i = 0; i < translationtables[TRANSLATION_LevelScripted].Size(); ++i)
|
|
||||||
{
|
|
||||||
trans = translationtables[TRANSLATION_LevelScripted][i];
|
|
||||||
if (trans != NULL && !trans->IsIdentity())
|
|
||||||
{
|
|
||||||
w = WORD(i);
|
|
||||||
arc << w;
|
|
||||||
trans->Serialize(arc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w = 0xffff;
|
|
||||||
arc << w;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
while (arc << w, w != 0xffff)
|
|
||||||
{
|
|
||||||
trans = translationtables[TRANSLATION_LevelScripted].GetVal(w);
|
|
||||||
if (trans == NULL)
|
|
||||||
{
|
|
||||||
trans = new FRemapTable;
|
|
||||||
translationtables[TRANSLATION_LevelScripted].SetVal(w, trans);
|
|
||||||
}
|
|
||||||
trans->Serialize(arc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This must be saved, too, of course!
|
|
||||||
FCanvasTextureInfo::Serialize (arc);
|
|
||||||
AM_SerializeMarkers(arc);
|
|
||||||
|
|
||||||
P_SerializePlayers (arc, hubLoad);
|
|
||||||
P_SerializeSounds (arc);
|
|
||||||
if (arc.IsLoading())
|
|
||||||
{
|
|
||||||
for (i = 0; i < numsectors; i++)
|
|
||||||
{
|
|
||||||
P_Recalculate3DFloors(§ors[i]);
|
|
||||||
}
|
|
||||||
for (i = 0; i < MAXPLAYERS; ++i)
|
|
||||||
{
|
|
||||||
if (playeringame[i] && players[i].mo != NULL)
|
|
||||||
{
|
|
||||||
players[i].mo->SetupWeaponSlots();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Renderer->EndSerialize(arc);
|
|
||||||
unsigned tt = I_MSTime();
|
|
||||||
Printf("Serialization took %d ms\n", tt - tm);
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// Archives the current level
|
// Archives the current level
|
||||||
|
|
496
src/json.cpp
496
src/json.cpp
|
@ -11,324 +11,6 @@
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
FSerializer &Serialize(FSerializer &arc, const char *key, line_t &line, line_t *def)
|
|
||||||
{
|
|
||||||
if (arc.BeginObject(key))
|
|
||||||
{
|
|
||||||
arc("flags", line.flags, def->flags)
|
|
||||||
("activation", line.activation, def->activation)
|
|
||||||
("special", line.special, def->special)
|
|
||||||
("alpha", line.alpha, def->alpha)
|
|
||||||
.Args("args", line.args, def->args, line.special)
|
|
||||||
("portalindex", line.portalindex, def->portalindex)
|
|
||||||
// no need to store the sidedef references. Unless the map loader is changed they will not change between map loads.
|
|
||||||
//.Array("sides", line.sidedef, 2)
|
|
||||||
.EndObject();
|
|
||||||
}
|
|
||||||
return arc;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
FSerializer &Serialize(FSerializer &arc, const char *key, side_t::part &part, side_t::part *def)
|
|
||||||
{
|
|
||||||
if (arc.canSkip() && def != nullptr && !memcmp(&part, def, sizeof(part)))
|
|
||||||
{
|
|
||||||
return arc;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (arc.BeginObject(key))
|
|
||||||
{
|
|
||||||
arc("xoffset", part.xOffset, def->xOffset)
|
|
||||||
("yoffset", part.yOffset, def->yOffset)
|
|
||||||
("xscale", part.xScale, def->xScale)
|
|
||||||
("yscale", part.yScale, def->yScale)
|
|
||||||
("texture", part.texture, def->texture)
|
|
||||||
("interpolation", part.interpolation)
|
|
||||||
.EndObject();
|
|
||||||
}
|
|
||||||
return arc;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
FSerializer &Serialize(FSerializer &arc, const char *key, side_t &side, side_t *def)
|
|
||||||
{
|
|
||||||
if (arc.BeginObject(key))
|
|
||||||
{
|
|
||||||
arc.Array("textures", side.textures, def->textures, 3, true)
|
|
||||||
("light", side.Light, def->Light)
|
|
||||||
("flags", side.Flags, def->Flags)
|
|
||||||
//("leftside", side.LeftSide)
|
|
||||||
//("rightside", side.RightSide)
|
|
||||||
//("index", side.Index)
|
|
||||||
("attacheddecals", side.AttachedDecals)
|
|
||||||
.EndObject();
|
|
||||||
}
|
|
||||||
return arc;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
FSerializer &Serialize(FSerializer &arc, const char *key, FLinkedSector &ls, FLinkedSector *def)
|
|
||||||
{
|
|
||||||
if (arc.BeginObject(key))
|
|
||||||
{
|
|
||||||
arc("sector", ls.Sector)
|
|
||||||
("type", ls.Type)
|
|
||||||
.EndObject();
|
|
||||||
}
|
|
||||||
return arc;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
FSerializer &Serialize(FSerializer &arc, const char *key, sector_t::splane &p, sector_t::splane *def)
|
|
||||||
{
|
|
||||||
if (arc.canSkip() && def != nullptr && !memcmp(&p, def, sizeof(p)))
|
|
||||||
{
|
|
||||||
return arc;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (arc.BeginObject(key))
|
|
||||||
{
|
|
||||||
arc("xoffs", p.xform.xOffs, def->xform.xOffs)
|
|
||||||
("yoffs", p.xform.yOffs, def->xform.yOffs)
|
|
||||||
("xscale", p.xform.xScale, def->xform.xScale)
|
|
||||||
("yscale", p.xform.yScale, def->xform.yScale)
|
|
||||||
("angle", p.xform.Angle, def->xform.Angle)
|
|
||||||
("baseyoffs", p.xform.baseyOffs, def->xform.baseyOffs)
|
|
||||||
("baseangle", p.xform.baseAngle, def->xform.baseAngle)
|
|
||||||
("flags", p.Flags, def->Flags)
|
|
||||||
("light", p.Light, def->Light)
|
|
||||||
("texture", p.Texture, def->Texture)
|
|
||||||
("texz", p.TexZ, def->TexZ)
|
|
||||||
("alpha", p.alpha, def->alpha)
|
|
||||||
.EndObject();
|
|
||||||
}
|
|
||||||
return arc;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
FSerializer &Serialize(FSerializer &arc, const char *key, secplane_t &p, secplane_t *def)
|
|
||||||
{
|
|
||||||
if (arc.canSkip() && def != nullptr && !memcmp(&p, def, sizeof(p)))
|
|
||||||
{
|
|
||||||
return arc;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (arc.BeginObject(key))
|
|
||||||
{
|
|
||||||
arc("normal", p.normal, def->normal)
|
|
||||||
("d", p.D, def->D)
|
|
||||||
.EndObject();
|
|
||||||
|
|
||||||
if (arc.isReading() && p.normal.Z != 0)
|
|
||||||
{
|
|
||||||
p.negiC = 1 / p.normal.Z;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return arc;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
FSerializer &Serialize(FSerializer &arc, const char *key, sector_t &p, sector_t *def)
|
|
||||||
{
|
|
||||||
if (arc.BeginObject(key))
|
|
||||||
{
|
|
||||||
arc("floorplane", p.floorplane, def->floorplane)
|
|
||||||
("ceilingplane", p.ceilingplane, def->ceilingplane)
|
|
||||||
("lightlevel", p.lightlevel, def->lightlevel)
|
|
||||||
("special", p.special, def->special)
|
|
||||||
("soundtraversed", p.soundtraversed, def->soundtraversed)
|
|
||||||
("seqtype", p.seqType, def->seqType)
|
|
||||||
("seqname", p.SeqName, def->SeqName)
|
|
||||||
("friction", p.friction, def->friction)
|
|
||||||
("movefactor", p.movefactor, def->movefactor)
|
|
||||||
("stairlock", p.stairlock, def->stairlock)
|
|
||||||
("prevsec", p.prevsec, def->prevsec)
|
|
||||||
("nextsec", p.nextsec, def->nextsec)
|
|
||||||
.Array("planes", p.planes, def->planes, 2, true)
|
|
||||||
//("heightsec", p.heightsec)
|
|
||||||
//("bottommap", p.bottommap)
|
|
||||||
//("midmap", p.midmap)
|
|
||||||
//("topmap", p.topmap)
|
|
||||||
("damageamount", p.damageamount, def->damageamount)
|
|
||||||
("damageinterval", p.damageinterval, def->damageinterval)
|
|
||||||
("leakydamage", p.leakydamage, def->leakydamage)
|
|
||||||
("damagetype", p.damagetype, def->damagetype)
|
|
||||||
("sky", p.sky, def->sky)
|
|
||||||
("moreflags", p.MoreFlags, def->MoreFlags)
|
|
||||||
("flags", p.Flags, def->Flags)
|
|
||||||
.Array("portals", p.Portals, def->Portals, 2, true)
|
|
||||||
("zonenumber", p.ZoneNumber, def->ZoneNumber)
|
|
||||||
.Array("interpolations", p.interpolations, 4, true)
|
|
||||||
("soundtarget", p.SoundTarget)
|
|
||||||
("secacttarget", p.SecActTarget)
|
|
||||||
("floordata", p.floordata)
|
|
||||||
("ceilingdata", p.ceilingdata)
|
|
||||||
("lightingdata", p.lightingdata)
|
|
||||||
("fakefloor_sectors", p.e->FakeFloor.Sectors)
|
|
||||||
("midtexf_lines", p.e->Midtex.Floor.AttachedLines)
|
|
||||||
("midtexf_sectors", p.e->Midtex.Floor.AttachedSectors)
|
|
||||||
("midtexc_lines", p.e->Midtex.Ceiling.AttachedLines)
|
|
||||||
("midtexc_sectors", p.e->Midtex.Ceiling.AttachedSectors)
|
|
||||||
("linked_floor", p.e->Linked.Floor.Sectors)
|
|
||||||
("linked_ceiling", p.e->Linked.Ceiling.Sectors)
|
|
||||||
("colormap", p.ColorMap, def->ColorMap)
|
|
||||||
.Terrain("floorterrain", p.terrainnum[0], &def->terrainnum[0])
|
|
||||||
.Terrain("ceilingterrain", p.terrainnum[1], &def->terrainnum[1])
|
|
||||||
.EndObject();
|
|
||||||
}
|
|
||||||
return arc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
FSerializer &Serialize(FSerializer &arc, const char *key, subsector_t *&ss, subsector_t **)
|
|
||||||
{
|
|
||||||
BYTE by;
|
|
||||||
const char *str;
|
|
||||||
|
|
||||||
if (arc.isWriting())
|
|
||||||
{
|
|
||||||
if (hasglnodes)
|
|
||||||
{
|
|
||||||
TArray<char> encoded(1 + (numsubsectors + 5) / 6);
|
|
||||||
int p = 0;
|
|
||||||
for (int i = 0; i < numsubsectors; i += 6)
|
|
||||||
{
|
|
||||||
by = 0;
|
|
||||||
for (int j = 0; j < 6; j++)
|
|
||||||
{
|
|
||||||
if (i + j < numsubsectors && (subsectors[i + j].flags & SSECF_DRAWN))
|
|
||||||
{
|
|
||||||
by |= (1 << j);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (by < 10) by += '0';
|
|
||||||
else if (by < 36) by += 'A' - 10;
|
|
||||||
else if (by < 62) by += 'a' - 36;
|
|
||||||
else if (by == 62) by = '-';
|
|
||||||
else if (by == 63) by = '+';
|
|
||||||
encoded[p++] = by;
|
|
||||||
}
|
|
||||||
encoded[p] = 0;
|
|
||||||
str = &encoded[0];
|
|
||||||
if (arc.BeginArray(key))
|
|
||||||
{
|
|
||||||
arc(nullptr, numvertexes)
|
|
||||||
(nullptr, numsubsectors)
|
|
||||||
.StringPtr(nullptr, str)
|
|
||||||
.EndArray();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int num_verts, num_subs;
|
|
||||||
|
|
||||||
if (arc.BeginArray(key))
|
|
||||||
{
|
|
||||||
arc(nullptr, num_verts)
|
|
||||||
(nullptr, num_subs)
|
|
||||||
.StringPtr(nullptr, str)
|
|
||||||
.EndArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return arc;
|
|
||||||
}
|
|
||||||
|
|
||||||
FSerializer &Serialize(FSerializer &arc, const char *key, ReverbContainer *&c, ReverbContainer **def)
|
|
||||||
{
|
|
||||||
int id = (arc.isReading() || c == nullptr) ? 0 : c->ID;
|
|
||||||
Serialize(arc, key, id, nullptr);
|
|
||||||
if (arc.isReading())
|
|
||||||
{
|
|
||||||
c = S_FindEnvironment(id);
|
|
||||||
}
|
|
||||||
return arc;
|
|
||||||
}
|
|
||||||
|
|
||||||
FSerializer &Serialize(FSerializer &arc, const char *key, zone_t &z, zone_t *def)
|
|
||||||
{
|
|
||||||
return Serialize(arc, key, z.Environment, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
//
|
|
||||||
// Save a line portal for savegames.
|
|
||||||
//
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
FSerializer &Serialize(FSerializer &arc, const char *key, FLinePortal &port, FLinePortal *def)
|
|
||||||
{
|
|
||||||
if (arc.BeginObject(key))
|
|
||||||
{
|
|
||||||
arc("origin", port.mOrigin)
|
|
||||||
("destination", port.mDestination)
|
|
||||||
("displacement", port.mDisplacement)
|
|
||||||
("type", port.mType)
|
|
||||||
("flags", port.mFlags)
|
|
||||||
("defflags", port.mDefFlags)
|
|
||||||
("align", port.mAlign)
|
|
||||||
.EndObject();
|
|
||||||
}
|
|
||||||
return arc;
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
//
|
|
||||||
// Save a sector portal for savegames.
|
|
||||||
//
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
FSerializer &Serialize(FSerializer &arc, const char *key, FSectorPortal &port, FSectorPortal *def)
|
|
||||||
{
|
|
||||||
if (arc.BeginObject(key))
|
|
||||||
{
|
|
||||||
arc("type", port.mType)
|
|
||||||
("flags", port.mFlags)
|
|
||||||
("partner", port.mPartner)
|
|
||||||
("plane", port.mPlane)
|
|
||||||
("origin", port.mOrigin)
|
|
||||||
("destination", port.mDestination)
|
|
||||||
("displacement", port.mDisplacement)
|
|
||||||
("planez", port.mPlaneZ)
|
|
||||||
("skybox", port.mSkybox)
|
|
||||||
.EndObject();
|
|
||||||
}
|
|
||||||
return arc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DThinker::SaveList(FSerializer &arc, DThinker *node)
|
void DThinker::SaveList(FSerializer &arc, DThinker *node)
|
||||||
{
|
{
|
||||||
if (node != NULL)
|
if (node != NULL)
|
||||||
|
@ -368,17 +50,6 @@ void DThinker::SerializeThinkers(FSerializer &arc, bool hubLoad)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void SerializeWorld(FSerializer &arc)
|
|
||||||
{
|
|
||||||
arc.Array("linedefs", lines, &loadlines[0], numlines)
|
|
||||||
.Array("sidedefs", sides, &loadsides[0], numsides)
|
|
||||||
.Array("sectors", sectors, &loadsectors[0], numsectors)
|
|
||||||
("subsectors", subsectors)
|
|
||||||
("zones", Zones)
|
|
||||||
("lineportals", linePortals)
|
|
||||||
("sectorportals", sectorPortals);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DObject::SerializeUserVars(FSerializer &arc)
|
void DObject::SerializeUserVars(FSerializer &arc)
|
||||||
{
|
{
|
||||||
PSymbolTable *symt;
|
PSymbolTable *symt;
|
||||||
|
@ -399,174 +70,9 @@ void DObject::SerializeUserVars(FSerializer &arc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DObject::Serialize(FSerializer &arc)
|
|
||||||
{
|
|
||||||
ObjectFlags |= OF_SerialSuccess;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// AActor :: Serialize
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
#define A(a,b) ((a), (b), def->b)
|
|
||||||
|
|
||||||
void AActor::Serialize(FSerializer &arc)
|
|
||||||
{
|
|
||||||
int damage = 0; // just a placeholder until the insanity surrounding the damage property can be fixed
|
|
||||||
AActor *def = GetDefault();
|
|
||||||
|
|
||||||
Super::Serialize(arc);
|
|
||||||
|
|
||||||
arc
|
|
||||||
.Sprite("sprite", sprite, &def->sprite)
|
|
||||||
A("pos", __Pos)
|
|
||||||
A("angles", Angles)
|
|
||||||
A("frame", frame)
|
|
||||||
A("scale", Scale)
|
|
||||||
A("renderstyle", RenderStyle)
|
|
||||||
A("renderflags", renderflags)
|
|
||||||
A("picnum", picnum)
|
|
||||||
A("floorpic", floorpic)
|
|
||||||
A("ceilingpic", ceilingpic)
|
|
||||||
A("tidtohate", TIDtoHate)
|
|
||||||
A("lastlookpn", LastLookPlayerNumber)
|
|
||||||
("lastlookactor", LastLookActor)
|
|
||||||
A("effects", effects)
|
|
||||||
A("alpha", Alpha)
|
|
||||||
A("fillcolor", fillcolor)
|
|
||||||
A("sector", Sector)
|
|
||||||
A("floorz", floorz)
|
|
||||||
A("ceilingz", ceilingz)
|
|
||||||
A("dropoffz", dropoffz)
|
|
||||||
A("floorsector", floorsector)
|
|
||||||
A("ceilingsector", ceilingsector)
|
|
||||||
A("radius", radius)
|
|
||||||
A("height", Height)
|
|
||||||
A("ppassheight", projectilepassheight)
|
|
||||||
A("vel", Vel)
|
|
||||||
A("tics", tics)
|
|
||||||
A("state", state)
|
|
||||||
("damage", damage)
|
|
||||||
.Terrain("floorterrain", floorterrain, &def->floorterrain)
|
|
||||||
A("projectilekickback", projectileKickback)
|
|
||||||
A("flags", flags)
|
|
||||||
A("flags2", flags2)
|
|
||||||
A("flags3", flags3)
|
|
||||||
A("flags4", flags4)
|
|
||||||
A("flags5", flags5)
|
|
||||||
A("flags6", flags6)
|
|
||||||
A("flags7", flags7)
|
|
||||||
A("weaponspecial", weaponspecial)
|
|
||||||
A("special1", special1)
|
|
||||||
A("special2", special2)
|
|
||||||
A("specialf1", specialf1)
|
|
||||||
A("specialf2", specialf2)
|
|
||||||
A("health", health)
|
|
||||||
A("movedir", movedir)
|
|
||||||
A("visdir", visdir)
|
|
||||||
A("movecount", movecount)
|
|
||||||
A("strafecount", strafecount)
|
|
||||||
("target", target)
|
|
||||||
("lastenemy", lastenemy)
|
|
||||||
("lastheard", LastHeard)
|
|
||||||
A("reactiontime", reactiontime)
|
|
||||||
A("threshold", threshold)
|
|
||||||
A("player", player)
|
|
||||||
A("spawnpoint", SpawnPoint)
|
|
||||||
A("spawnangle", SpawnAngle)
|
|
||||||
A("starthealth", StartHealth)
|
|
||||||
A("skillrespawncount", skillrespawncount)
|
|
||||||
("tracer", tracer)
|
|
||||||
A("floorclip", Floorclip)
|
|
||||||
A("tid", tid)
|
|
||||||
A("special", special)
|
|
||||||
.Args("args", args, def->args, special)
|
|
||||||
A("accuracy", accuracy)
|
|
||||||
A("stamina", stamina)
|
|
||||||
("goal", goal)
|
|
||||||
A("waterlevel", waterlevel)
|
|
||||||
A("minmissilechance", MinMissileChance)
|
|
||||||
A("spawnflags", SpawnFlags)
|
|
||||||
("inventory", Inventory)
|
|
||||||
A("inventoryid", InventoryID)
|
|
||||||
A("floatbobphase", FloatBobPhase)
|
|
||||||
A("translation", Translation)
|
|
||||||
A("seesound", SeeSound)
|
|
||||||
A("attacksound", AttackSound)
|
|
||||||
A("paimsound", PainSound)
|
|
||||||
A("deathsound", DeathSound)
|
|
||||||
A("activesound", ActiveSound)
|
|
||||||
A("usesound", UseSound)
|
|
||||||
A("bouncesound", BounceSound)
|
|
||||||
A("wallbouncesound", WallBounceSound)
|
|
||||||
A("crushpainsound", CrushPainSound)
|
|
||||||
A("speed", Speed)
|
|
||||||
A("floatspeed", FloatSpeed)
|
|
||||||
A("mass", Mass)
|
|
||||||
A("painchance", PainChance)
|
|
||||||
A("spawnstate", SpawnState)
|
|
||||||
A("seestate", SeeState)
|
|
||||||
A("meleestate", MeleeState)
|
|
||||||
A("missilestate", MissileState)
|
|
||||||
A("maxdropoffheight", MaxDropOffHeight)
|
|
||||||
A("maxstepheight", MaxStepHeight)
|
|
||||||
A("bounceflags", BounceFlags)
|
|
||||||
A("bouncefactor", bouncefactor)
|
|
||||||
A("wallbouncefactor", wallbouncefactor)
|
|
||||||
A("bouncecount", bouncecount)
|
|
||||||
A("maxtargetrange", maxtargetrange)
|
|
||||||
A("meleethreshold", meleethreshold)
|
|
||||||
A("meleerange", meleerange)
|
|
||||||
A("damagetype", DamageType)
|
|
||||||
A("damagetypereceived", DamageTypeReceived)
|
|
||||||
A("paintype", PainType)
|
|
||||||
A("deathtype", DeathType)
|
|
||||||
A("gravity", Gravity)
|
|
||||||
A("fastchasestrafecount", FastChaseStrafeCount)
|
|
||||||
("master", master)
|
|
||||||
A("smokecounter", smokecounter)
|
|
||||||
("blockingmobj", BlockingMobj)
|
|
||||||
A("blockingline", BlockingLine)
|
|
||||||
A("visibletoteam", VisibleToTeam)
|
|
||||||
A("pushfactor", pushfactor)
|
|
||||||
A("species", Species)
|
|
||||||
A("score", Score)
|
|
||||||
A("designatedteam", DesignatedTeam)
|
|
||||||
A("lastpush", lastpush)
|
|
||||||
A("lastbump", lastbump)
|
|
||||||
A("painthreshold", PainThreshold)
|
|
||||||
A("damagefactor", DamageFactor)
|
|
||||||
A("damagemultiply", DamageMultiply)
|
|
||||||
A("waveindexxy", WeaveIndexXY)
|
|
||||||
A("weaveindexz", WeaveIndexZ)
|
|
||||||
A("pdmgreceived", PoisonDamageReceived)
|
|
||||||
A("pdurreceived", PoisonDurationReceived)
|
|
||||||
A("ppreceived", PoisonPeriodReceived)
|
|
||||||
("poisoner", Poisoner)
|
|
||||||
A("posiondamage", PoisonDamage)
|
|
||||||
A("poisonduration", PoisonDuration)
|
|
||||||
A("poisonperiod", PoisonPeriod)
|
|
||||||
A("poisondamagetype", PoisonDamageType)
|
|
||||||
A("poisondmgtypereceived", PoisonDamageTypeReceived)
|
|
||||||
A("conversationroot", ConversationRoot)
|
|
||||||
A("conversation", Conversation)
|
|
||||||
A("friendplayer", FriendPlayer)
|
|
||||||
A("telefogsourcetype", TeleFogSourceType)
|
|
||||||
A("telefogdesttype", TeleFogDestType)
|
|
||||||
A("ripperlevel", RipperLevel)
|
|
||||||
A("riplevelmin", RipLevelMin)
|
|
||||||
A("riplevelmax", RipLevelMax)
|
|
||||||
A("devthreshold", DefThreshold)
|
|
||||||
A("spriteangle", SpriteAngle)
|
|
||||||
A("spriterotation", SpriteRotation)
|
|
||||||
("alternative", alternative)
|
|
||||||
A("tag", Tag);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
void SerializeWorld(FSerializer &arc);
|
||||||
|
|
||||||
|
|
||||||
CCMD(writejson)
|
CCMD(writejson)
|
||||||
{
|
{
|
||||||
|
|
388
src/p_mobj.cpp
388
src/p_mobj.cpp
|
@ -70,6 +70,7 @@
|
||||||
#include "po_man.h"
|
#include "po_man.h"
|
||||||
#include "p_spec.h"
|
#include "p_spec.h"
|
||||||
#include "p_checkposition.h"
|
#include "p_checkposition.h"
|
||||||
|
#include "serializer.h"
|
||||||
|
|
||||||
// MACROS ------------------------------------------------------------------
|
// MACROS ------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -155,214 +156,195 @@ AActor::~AActor ()
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void AActor::Serialize(FArchive &arc)
|
#define A(a,b) ((a), (b), def->b)
|
||||||
|
|
||||||
|
void AActor::Serialize(FSerializer &arc)
|
||||||
{
|
{
|
||||||
|
AActor *def = GetDefault();
|
||||||
|
|
||||||
Super::Serialize(arc);
|
Super::Serialize(arc);
|
||||||
|
|
||||||
if (arc.IsStoring())
|
arc
|
||||||
{
|
.Sprite("sprite", sprite, &def->sprite)
|
||||||
arc.WriteSprite(sprite);
|
A("pos", __Pos)
|
||||||
}
|
A("angles", Angles)
|
||||||
else
|
A("frame", frame)
|
||||||
{
|
A("scale", Scale)
|
||||||
sprite = arc.ReadSprite();
|
A("renderstyle", RenderStyle)
|
||||||
}
|
A("renderflags", renderflags)
|
||||||
|
A("picnum", picnum)
|
||||||
arc << __Pos
|
A("floorpic", floorpic)
|
||||||
<< Angles.Yaw
|
A("ceilingpic", ceilingpic)
|
||||||
<< Angles.Pitch
|
A("tidtohate", TIDtoHate)
|
||||||
<< Angles.Roll
|
A("lastlookpn", LastLookPlayerNumber)
|
||||||
<< frame
|
("lastlookactor", LastLookActor)
|
||||||
<< Scale
|
A("effects", effects)
|
||||||
<< RenderStyle
|
A("alpha", Alpha)
|
||||||
<< renderflags
|
A("fillcolor", fillcolor)
|
||||||
<< picnum
|
A("sector", Sector)
|
||||||
<< floorpic
|
A("floorz", floorz)
|
||||||
<< ceilingpic
|
A("ceilingz", ceilingz)
|
||||||
<< TIDtoHate
|
A("dropoffz", dropoffz)
|
||||||
<< LastLookPlayerNumber
|
A("floorsector", floorsector)
|
||||||
<< LastLookActor
|
A("ceilingsector", ceilingsector)
|
||||||
<< effects
|
A("radius", radius)
|
||||||
<< Alpha
|
A("height", Height)
|
||||||
<< fillcolor
|
A("ppassheight", projectilepassheight)
|
||||||
<< Sector
|
A("vel", Vel)
|
||||||
<< floorz
|
A("tics", tics)
|
||||||
<< ceilingz
|
A("state", state)
|
||||||
<< dropoffz
|
A("damage", DamageVal)
|
||||||
<< floorsector
|
.Terrain("floorterrain", floorterrain, &def->floorterrain)
|
||||||
<< ceilingsector
|
A("projectilekickback", projectileKickback)
|
||||||
<< radius
|
A("flags", flags)
|
||||||
<< Height
|
A("flags2", flags2)
|
||||||
<< projectilepassheight
|
A("flags3", flags3)
|
||||||
<< Vel
|
A("flags4", flags4)
|
||||||
<< tics
|
A("flags5", flags5)
|
||||||
<< state
|
A("flags6", flags6)
|
||||||
<< DamageVal;
|
A("flags7", flags7)
|
||||||
if (DamageVal == 0x40000000 || DamageVal == -1)
|
A("weaponspecial", weaponspecial)
|
||||||
{
|
A("special1", special1)
|
||||||
DamageVal = -1;
|
A("special2", special2)
|
||||||
DamageFunc = GetDefault()->DamageFunc;
|
A("specialf1", specialf1)
|
||||||
}
|
A("specialf2", specialf2)
|
||||||
else
|
A("health", health)
|
||||||
{
|
A("movedir", movedir)
|
||||||
DamageFunc = nullptr;
|
A("visdir", visdir)
|
||||||
}
|
A("movecount", movecount)
|
||||||
P_SerializeTerrain(arc, floorterrain);
|
A("strafecount", strafecount)
|
||||||
arc << projectileKickback
|
("target", target)
|
||||||
<< flags
|
("lastenemy", lastenemy)
|
||||||
<< flags2
|
("lastheard", LastHeard)
|
||||||
<< flags3
|
A("reactiontime", reactiontime)
|
||||||
<< flags4
|
A("threshold", threshold)
|
||||||
<< flags5
|
A("player", player)
|
||||||
<< flags6
|
A("spawnpoint", SpawnPoint)
|
||||||
<< flags7
|
A("spawnangle", SpawnAngle)
|
||||||
<< weaponspecial
|
A("starthealth", StartHealth)
|
||||||
<< special1
|
A("skillrespawncount", skillrespawncount)
|
||||||
<< special2
|
("tracer", tracer)
|
||||||
<< specialf1
|
A("floorclip", Floorclip)
|
||||||
<< specialf2
|
A("tid", tid)
|
||||||
<< health
|
A("special", special)
|
||||||
<< movedir
|
.Args("args", args, def->args, special)
|
||||||
<< visdir
|
A("accuracy", accuracy)
|
||||||
<< movecount
|
A("stamina", stamina)
|
||||||
<< strafecount
|
("goal", goal)
|
||||||
<< target
|
A("waterlevel", waterlevel)
|
||||||
<< lastenemy
|
A("minmissilechance", MinMissileChance)
|
||||||
<< LastHeard
|
A("spawnflags", SpawnFlags)
|
||||||
<< reactiontime
|
("inventory", Inventory)
|
||||||
<< threshold
|
A("inventoryid", InventoryID)
|
||||||
<< player
|
A("floatbobphase", FloatBobPhase)
|
||||||
<< SpawnPoint
|
A("translation", Translation)
|
||||||
<< SpawnAngle
|
A("seesound", SeeSound)
|
||||||
<< StartHealth
|
A("attacksound", AttackSound)
|
||||||
<< skillrespawncount
|
A("paimsound", PainSound)
|
||||||
<< tracer
|
A("deathsound", DeathSound)
|
||||||
<< Floorclip
|
A("activesound", ActiveSound)
|
||||||
<< tid
|
A("usesound", UseSound)
|
||||||
<< special;
|
A("bouncesound", BounceSound)
|
||||||
if (P_IsACSSpecial(special))
|
A("wallbouncesound", WallBounceSound)
|
||||||
{
|
A("crushpainsound", CrushPainSound)
|
||||||
P_SerializeACSScriptNumber(arc, args[0], false);
|
A("speed", Speed)
|
||||||
}
|
A("floatspeed", FloatSpeed)
|
||||||
else
|
A("mass", Mass)
|
||||||
{
|
A("painchance", PainChance)
|
||||||
arc << args[0];
|
A("spawnstate", SpawnState)
|
||||||
}
|
A("seestate", SeeState)
|
||||||
arc << args[1] << args[2] << args[3] << args[4];
|
A("meleestate", MeleeState)
|
||||||
arc << accuracy << stamina;
|
A("missilestate", MissileState)
|
||||||
arc << goal
|
A("maxdropoffheight", MaxDropOffHeight)
|
||||||
<< waterlevel
|
A("maxstepheight", MaxStepHeight)
|
||||||
<< MinMissileChance
|
A("bounceflags", BounceFlags)
|
||||||
<< SpawnFlags
|
A("bouncefactor", bouncefactor)
|
||||||
<< Inventory
|
A("wallbouncefactor", wallbouncefactor)
|
||||||
<< InventoryID;
|
A("bouncecount", bouncecount)
|
||||||
arc << FloatBobPhase
|
A("maxtargetrange", maxtargetrange)
|
||||||
<< Translation
|
A("meleethreshold", meleethreshold)
|
||||||
<< SeeSound
|
A("meleerange", meleerange)
|
||||||
<< AttackSound
|
A("damagetype", DamageType)
|
||||||
<< PainSound
|
A("damagetypereceived", DamageTypeReceived)
|
||||||
<< DeathSound
|
A("paintype", PainType)
|
||||||
<< ActiveSound
|
A("deathtype", DeathType)
|
||||||
<< UseSound
|
A("gravity", Gravity)
|
||||||
<< BounceSound
|
A("fastchasestrafecount", FastChaseStrafeCount)
|
||||||
<< WallBounceSound
|
("master", master)
|
||||||
<< CrushPainSound
|
A("smokecounter", smokecounter)
|
||||||
<< Speed
|
("blockingmobj", BlockingMobj)
|
||||||
<< FloatSpeed
|
A("blockingline", BlockingLine)
|
||||||
<< Mass
|
A("visibletoteam", VisibleToTeam)
|
||||||
<< PainChance
|
A("pushfactor", pushfactor)
|
||||||
<< SpawnState
|
A("species", Species)
|
||||||
<< SeeState
|
A("score", Score)
|
||||||
<< MeleeState
|
A("designatedteam", DesignatedTeam)
|
||||||
<< MissileState
|
A("lastpush", lastpush)
|
||||||
<< MaxDropOffHeight
|
A("lastbump", lastbump)
|
||||||
<< MaxStepHeight
|
A("painthreshold", PainThreshold)
|
||||||
<< BounceFlags
|
A("damagefactor", DamageFactor)
|
||||||
<< bouncefactor
|
A("damagemultiply", DamageMultiply)
|
||||||
<< wallbouncefactor
|
A("waveindexxy", WeaveIndexXY)
|
||||||
<< bouncecount
|
A("weaveindexz", WeaveIndexZ)
|
||||||
<< maxtargetrange
|
A("pdmgreceived", PoisonDamageReceived)
|
||||||
<< meleethreshold
|
A("pdurreceived", PoisonDurationReceived)
|
||||||
<< meleerange
|
A("ppreceived", PoisonPeriodReceived)
|
||||||
<< DamageType;
|
("poisoner", Poisoner)
|
||||||
arc << DamageTypeReceived;
|
A("posiondamage", PoisonDamage)
|
||||||
arc << PainType
|
A("poisonduration", PoisonDuration)
|
||||||
<< DeathType;
|
A("poisonperiod", PoisonPeriod)
|
||||||
arc << Gravity
|
A("poisondamagetype", PoisonDamageType)
|
||||||
<< FastChaseStrafeCount
|
A("poisondmgtypereceived", PoisonDamageTypeReceived)
|
||||||
<< master
|
A("conversationroot", ConversationRoot)
|
||||||
<< smokecounter
|
A("conversation", Conversation)
|
||||||
<< BlockingMobj
|
A("friendplayer", FriendPlayer)
|
||||||
<< BlockingLine
|
A("telefogsourcetype", TeleFogSourceType)
|
||||||
<< VisibleToTeam // [BB]
|
A("telefogdesttype", TeleFogDestType)
|
||||||
<< pushfactor
|
A("ripperlevel", RipperLevel)
|
||||||
<< Species
|
A("riplevelmin", RipLevelMin)
|
||||||
<< Score;
|
A("riplevelmax", RipLevelMax)
|
||||||
arc << DesignatedTeam;
|
A("devthreshold", DefThreshold)
|
||||||
arc << lastpush << lastbump
|
A("spriteangle", SpriteAngle)
|
||||||
<< PainThreshold
|
A("spriterotation", SpriteRotation)
|
||||||
<< DamageFactor;
|
("alternative", alternative)
|
||||||
arc << DamageMultiply;
|
A("tag", Tag);
|
||||||
arc << WeaveIndexXY << WeaveIndexZ
|
|
||||||
<< PoisonDamageReceived << PoisonDurationReceived << PoisonPeriodReceived << Poisoner
|
|
||||||
<< PoisonDamage << PoisonDuration << PoisonPeriod;
|
|
||||||
arc << PoisonDamageType << PoisonDamageTypeReceived;
|
|
||||||
arc << ConversationRoot << Conversation;
|
|
||||||
arc << FriendPlayer;
|
|
||||||
arc << TeleFogSourceType
|
|
||||||
<< TeleFogDestType;
|
|
||||||
arc << RipperLevel
|
|
||||||
<< RipLevelMin
|
|
||||||
<< RipLevelMax;
|
|
||||||
arc << DefThreshold;
|
|
||||||
if (SaveVersion >= 4549)
|
|
||||||
{
|
|
||||||
arc << SpriteAngle;
|
|
||||||
arc << SpriteRotation;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SaveVersion >= 4550)
|
|
||||||
{
|
|
||||||
arc << alternative;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
FString tagstr;
|
|
||||||
if (arc.IsStoring() && Tag != NULL && Tag->Len() > 0) tagstr = *Tag;
|
|
||||||
arc << tagstr;
|
|
||||||
if (arc.IsLoading())
|
|
||||||
{
|
|
||||||
if (tagstr.Len() == 0) Tag = NULL;
|
|
||||||
else Tag = mStringPropertyData.Alloc(tagstr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (arc.IsLoading ())
|
|
||||||
{
|
|
||||||
touching_sectorlist = NULL;
|
|
||||||
LinkToWorld(false, Sector);
|
|
||||||
|
|
||||||
AddToHash ();
|
|
||||||
SetShade (fillcolor);
|
|
||||||
if (player)
|
|
||||||
{
|
|
||||||
if (playeringame[player - players] &&
|
|
||||||
player->cls != NULL &&
|
|
||||||
!(flags4 & MF4_NOSKIN) &&
|
|
||||||
state->sprite == GetDefaultByType (player->cls)->SpawnState->sprite)
|
|
||||||
{ // Give player back the skin
|
|
||||||
sprite = skins[player->userinfo.GetSkin()].sprite;
|
|
||||||
}
|
|
||||||
if (Speed == 0)
|
|
||||||
{
|
|
||||||
Speed = GetDefault()->Speed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ClearInterpolation();
|
|
||||||
UpdateWaterLevel(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef A
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// This must be done after the world is set up.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void AActor::PostSerialize()
|
||||||
|
{
|
||||||
|
touching_sectorlist = NULL;
|
||||||
|
LinkToWorld(false, Sector);
|
||||||
|
|
||||||
|
AddToHash();
|
||||||
|
SetShade(fillcolor);
|
||||||
|
if (player)
|
||||||
|
{
|
||||||
|
if (playeringame[player - players] &&
|
||||||
|
player->cls != NULL &&
|
||||||
|
!(flags4 & MF4_NOSKIN) &&
|
||||||
|
state->sprite == GetDefaultByType(player->cls)->SpawnState->sprite)
|
||||||
|
{ // Give player back the skin
|
||||||
|
sprite = skins[player->userinfo.GetSkin()].sprite;
|
||||||
|
}
|
||||||
|
if (Speed == 0)
|
||||||
|
{
|
||||||
|
Speed = GetDefault()->Speed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ClearInterpolation();
|
||||||
|
UpdateWaterLevel(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AActor::AActor () throw()
|
AActor::AActor () throw()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
775
src/p_saveg.cpp
775
src/p_saveg.cpp
|
@ -3,7 +3,8 @@
|
||||||
** Code for serializing the world state in an archive
|
** Code for serializing the world state in an archive
|
||||||
**
|
**
|
||||||
**---------------------------------------------------------------------------
|
**---------------------------------------------------------------------------
|
||||||
** Copyright 1998-2006 Randy Heit
|
** Copyright 1998-2016 Randy Heit
|
||||||
|
** Copyright 2005-2016 Christoph Oelckers
|
||||||
** All rights reserved.
|
** All rights reserved.
|
||||||
**
|
**
|
||||||
** Redistribution and use in source and binary forms, with or without
|
** Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -55,18 +56,22 @@
|
||||||
#include "p_lnspec.h"
|
#include "p_lnspec.h"
|
||||||
#include "p_acs.h"
|
#include "p_acs.h"
|
||||||
#include "p_terrain.h"
|
#include "p_terrain.h"
|
||||||
|
#include "am_map.h"
|
||||||
|
#include "r_data/r_translate.h"
|
||||||
|
#include "sbar.h"
|
||||||
|
#include "r_utility.h"
|
||||||
|
#include "r_sky.h"
|
||||||
|
#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"
|
||||||
|
|
||||||
void CopyPlayer (player_t *dst, player_t *src, const char *name);
|
void CopyPlayer (player_t *dst, player_t *src, const char *name);
|
||||||
static void ReadOnePlayer (FArchive &arc, bool skipload);
|
static void ReadOnePlayer (FArchive &arc, bool skipload);
|
||||||
static void ReadMultiplePlayers (FArchive &arc, int numPlayers, int numPlayersNow, bool skipload);
|
static void ReadMultiplePlayers (FArchive &arc, int numPlayers, int numPlayersNow, bool skipload);
|
||||||
static void SpawnExtraPlayers ();
|
static void SpawnExtraPlayers ();
|
||||||
|
|
||||||
inline FArchive &operator<< (FArchive &arc, FLinkedSector &link)
|
|
||||||
{
|
|
||||||
arc << link.Sector << link.Type;
|
|
||||||
return arc;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// P_ArchivePlayers
|
// P_ArchivePlayers
|
||||||
//
|
//
|
||||||
|
@ -339,179 +344,6 @@ static void SpawnExtraPlayers ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// P_ArchiveWorld
|
|
||||||
//
|
|
||||||
void P_SerializeWorld (FArchive &arc)
|
|
||||||
{
|
|
||||||
int i, j;
|
|
||||||
sector_t *sec;
|
|
||||||
line_t *li;
|
|
||||||
zone_t *zn;
|
|
||||||
|
|
||||||
// do sectors
|
|
||||||
for (i = 0, sec = sectors; i < numsectors; i++, sec++)
|
|
||||||
{
|
|
||||||
arc << sec->floorplane
|
|
||||||
<< sec->ceilingplane;
|
|
||||||
arc << sec->lightlevel;
|
|
||||||
arc << sec->special;
|
|
||||||
arc << sec->soundtraversed
|
|
||||||
<< sec->seqType
|
|
||||||
<< sec->friction
|
|
||||||
<< sec->movefactor
|
|
||||||
<< sec->stairlock
|
|
||||||
<< sec->prevsec
|
|
||||||
<< sec->nextsec
|
|
||||||
<< sec->planes[sector_t::floor]
|
|
||||||
<< sec->planes[sector_t::ceiling]
|
|
||||||
<< sec->heightsec
|
|
||||||
<< sec->bottommap << sec->midmap << sec->topmap
|
|
||||||
<< sec->gravity;
|
|
||||||
P_SerializeTerrain(arc, sec->terrainnum[0]);
|
|
||||||
P_SerializeTerrain(arc, sec->terrainnum[1]);
|
|
||||||
arc << sec->damageamount;
|
|
||||||
arc << sec->damageinterval
|
|
||||||
<< sec->leakydamage
|
|
||||||
<< sec->damagetype
|
|
||||||
<< sec->sky
|
|
||||||
<< sec->MoreFlags
|
|
||||||
<< sec->Flags
|
|
||||||
<< sec->Portals[sector_t::floor] << sec->Portals[sector_t::ceiling]
|
|
||||||
<< sec->ZoneNumber;
|
|
||||||
arc << sec->interpolations[0]
|
|
||||||
<< sec->interpolations[1]
|
|
||||||
<< sec->interpolations[2]
|
|
||||||
<< sec->interpolations[3]
|
|
||||||
<< sec->SeqName;
|
|
||||||
|
|
||||||
sec->e->Serialize(arc);
|
|
||||||
if (arc.IsStoring ())
|
|
||||||
{
|
|
||||||
arc << sec->ColorMap->Color
|
|
||||||
<< sec->ColorMap->Fade;
|
|
||||||
BYTE sat = sec->ColorMap->Desaturate;
|
|
||||||
arc << sat;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PalEntry color, fade;
|
|
||||||
BYTE desaturate;
|
|
||||||
arc << color << fade
|
|
||||||
<< desaturate;
|
|
||||||
sec->ColorMap = GetSpecialLights (color, fade, desaturate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// do lines
|
|
||||||
for (i = 0, li = lines; i < numlines; i++, li++)
|
|
||||||
{
|
|
||||||
arc << li->flags
|
|
||||||
<< li->activation
|
|
||||||
<< li->special
|
|
||||||
<< li->alpha;
|
|
||||||
|
|
||||||
if (P_IsACSSpecial(li->special))
|
|
||||||
{
|
|
||||||
P_SerializeACSScriptNumber(arc, li->args[0], false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
arc << li->args[0];
|
|
||||||
}
|
|
||||||
arc << li->args[1] << li->args[2] << li->args[3] << li->args[4];
|
|
||||||
|
|
||||||
arc << li->portalindex;
|
|
||||||
for (j = 0; j < 2; j++)
|
|
||||||
{
|
|
||||||
if (li->sidedef[j] == NULL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
side_t *si = li->sidedef[j];
|
|
||||||
arc << si->textures[side_t::top]
|
|
||||||
<< si->textures[side_t::mid]
|
|
||||||
<< si->textures[side_t::bottom]
|
|
||||||
<< si->Light
|
|
||||||
<< si->Flags
|
|
||||||
<< si->LeftSide
|
|
||||||
<< si->RightSide
|
|
||||||
<< si->Index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// do zones
|
|
||||||
unsigned numzones = Zones.Size();
|
|
||||||
arc << numzones;
|
|
||||||
|
|
||||||
if (arc.IsLoading())
|
|
||||||
{
|
|
||||||
Zones.Resize(numzones);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0, zn = &Zones[0]; i < numzones; ++i, ++zn)
|
|
||||||
{
|
|
||||||
arc << zn->Environment;
|
|
||||||
}
|
|
||||||
|
|
||||||
arc << linePortals << sectorPortals;
|
|
||||||
P_CollectLinkedPortals();
|
|
||||||
}
|
|
||||||
|
|
||||||
void P_SerializeWorldActors(FArchive &arc)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
sector_t *sec;
|
|
||||||
line_t *line;
|
|
||||||
|
|
||||||
for (i = 0, sec = sectors; i < numsectors; i++, sec++)
|
|
||||||
{
|
|
||||||
arc << sec->SoundTarget
|
|
||||||
<< sec->SecActTarget
|
|
||||||
<< sec->floordata
|
|
||||||
<< sec->ceilingdata
|
|
||||||
<< sec->lightingdata;
|
|
||||||
}
|
|
||||||
for (auto &s : sectorPortals)
|
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
arc << FakeFloor.Sectors
|
|
||||||
<< Midtex.Floor.AttachedLines
|
|
||||||
<< Midtex.Floor.AttachedSectors
|
|
||||||
<< Midtex.Ceiling.AttachedLines
|
|
||||||
<< Midtex.Ceiling.AttachedSectors
|
|
||||||
<< Linked.Floor.Sectors
|
|
||||||
<< Linked.Ceiling.Sectors;
|
|
||||||
}
|
|
||||||
|
|
||||||
FArchive &operator<< (FArchive &arc, side_t::part &p)
|
|
||||||
{
|
|
||||||
arc << p.xOffset << p.yOffset << p.interpolation << p.texture
|
|
||||||
<< p.xScale << p.yScale;// << p.Light;
|
|
||||||
return arc;
|
|
||||||
}
|
|
||||||
|
|
||||||
FArchive &operator<< (FArchive &arc, sector_t::splane &p)
|
|
||||||
{
|
|
||||||
arc << p.xform.xOffs << p.xform.yOffs << p.xform.xScale << p.xform.yScale
|
|
||||||
<< p.xform.Angle << p.xform.baseyOffs << p.xform.baseAngle
|
|
||||||
<< p.Flags << p.Light << p.Texture << p.TexZ << p.alpha;
|
|
||||||
return arc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -537,6 +369,411 @@ void P_DestroyThinkers(bool hubLoad)
|
||||||
DThinker::DestroyAllThinkers();
|
DThinker::DestroyAllThinkers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
FSerializer &Serialize(FSerializer &arc, const char *key, line_t &line, line_t *def)
|
||||||
|
{
|
||||||
|
if (arc.BeginObject(key))
|
||||||
|
{
|
||||||
|
arc("flags", line.flags, def->flags)
|
||||||
|
("activation", line.activation, def->activation)
|
||||||
|
("special", line.special, def->special)
|
||||||
|
("alpha", line.alpha, def->alpha)
|
||||||
|
.Args("args", line.args, def->args, line.special)
|
||||||
|
("portalindex", line.portalindex, def->portalindex)
|
||||||
|
// Unless the map loader is changed the sidedef references will not change between map loads so there's no need to save them.
|
||||||
|
//.Array("sides", line.sidedef, 2)
|
||||||
|
.EndObject();
|
||||||
|
}
|
||||||
|
return arc;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
FSerializer &Serialize(FSerializer &arc, const char *key, side_t::part &part, side_t::part *def)
|
||||||
|
{
|
||||||
|
if (arc.canSkip() && def != nullptr && !memcmp(&part, def, sizeof(part)))
|
||||||
|
{
|
||||||
|
return arc;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arc.BeginObject(key))
|
||||||
|
{
|
||||||
|
arc("xoffset", part.xOffset, def->xOffset)
|
||||||
|
("yoffset", part.yOffset, def->yOffset)
|
||||||
|
("xscale", part.xScale, def->xScale)
|
||||||
|
("yscale", part.yScale, def->yScale)
|
||||||
|
("texture", part.texture, def->texture)
|
||||||
|
("interpolation", part.interpolation)
|
||||||
|
.EndObject();
|
||||||
|
}
|
||||||
|
return arc;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
FSerializer &Serialize(FSerializer &arc, const char *key, side_t &side, side_t *def)
|
||||||
|
{
|
||||||
|
if (arc.BeginObject(key))
|
||||||
|
{
|
||||||
|
arc.Array("textures", side.textures, def->textures, 3, true)
|
||||||
|
("light", side.Light, def->Light)
|
||||||
|
("flags", side.Flags, def->Flags)
|
||||||
|
// These also remain identical across map loads
|
||||||
|
//("leftside", side.LeftSide)
|
||||||
|
//("rightside", side.RightSide)
|
||||||
|
//("index", side.Index)
|
||||||
|
("attacheddecals", side.AttachedDecals)
|
||||||
|
.EndObject();
|
||||||
|
}
|
||||||
|
return arc;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
FSerializer &Serialize(FSerializer &arc, const char *key, FLinkedSector &ls, FLinkedSector *def)
|
||||||
|
{
|
||||||
|
if (arc.BeginObject(key))
|
||||||
|
{
|
||||||
|
arc("sector", ls.Sector)
|
||||||
|
("type", ls.Type)
|
||||||
|
.EndObject();
|
||||||
|
}
|
||||||
|
return arc;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
FSerializer &Serialize(FSerializer &arc, const char *key, sector_t::splane &p, sector_t::splane *def)
|
||||||
|
{
|
||||||
|
if (arc.canSkip() && def != nullptr && !memcmp(&p, def, sizeof(p)))
|
||||||
|
{
|
||||||
|
return arc;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arc.BeginObject(key))
|
||||||
|
{
|
||||||
|
arc("xoffs", p.xform.xOffs, def->xform.xOffs)
|
||||||
|
("yoffs", p.xform.yOffs, def->xform.yOffs)
|
||||||
|
("xscale", p.xform.xScale, def->xform.xScale)
|
||||||
|
("yscale", p.xform.yScale, def->xform.yScale)
|
||||||
|
("angle", p.xform.Angle, def->xform.Angle)
|
||||||
|
("baseyoffs", p.xform.baseyOffs, def->xform.baseyOffs)
|
||||||
|
("baseangle", p.xform.baseAngle, def->xform.baseAngle)
|
||||||
|
("flags", p.Flags, def->Flags)
|
||||||
|
("light", p.Light, def->Light)
|
||||||
|
("texture", p.Texture, def->Texture)
|
||||||
|
("texz", p.TexZ, def->TexZ)
|
||||||
|
("alpha", p.alpha, def->alpha)
|
||||||
|
.EndObject();
|
||||||
|
}
|
||||||
|
return arc;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
FSerializer &Serialize(FSerializer &arc, const char *key, secplane_t &p, secplane_t *def)
|
||||||
|
{
|
||||||
|
if (arc.canSkip() && def != nullptr && !memcmp(&p, def, sizeof(p)))
|
||||||
|
{
|
||||||
|
return arc;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arc.BeginObject(key))
|
||||||
|
{
|
||||||
|
arc("normal", p.normal, def->normal)
|
||||||
|
("d", p.D, def->D)
|
||||||
|
.EndObject();
|
||||||
|
|
||||||
|
if (arc.isReading() && p.normal.Z != 0)
|
||||||
|
{
|
||||||
|
p.negiC = 1 / p.normal.Z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return arc;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
FSerializer &Serialize(FSerializer &arc, const char *key, sector_t &p, sector_t *def)
|
||||||
|
{
|
||||||
|
if (arc.BeginObject(key))
|
||||||
|
{
|
||||||
|
arc("floorplane", p.floorplane, def->floorplane)
|
||||||
|
("ceilingplane", p.ceilingplane, def->ceilingplane)
|
||||||
|
("lightlevel", p.lightlevel, def->lightlevel)
|
||||||
|
("special", p.special, def->special)
|
||||||
|
("soundtraversed", p.soundtraversed, def->soundtraversed)
|
||||||
|
("seqtype", p.seqType, def->seqType)
|
||||||
|
("seqname", p.SeqName, def->SeqName)
|
||||||
|
("friction", p.friction, def->friction)
|
||||||
|
("movefactor", p.movefactor, def->movefactor)
|
||||||
|
("stairlock", p.stairlock, def->stairlock)
|
||||||
|
("prevsec", p.prevsec, def->prevsec)
|
||||||
|
("nextsec", p.nextsec, def->nextsec)
|
||||||
|
.Array("planes", p.planes, def->planes, 2, true)
|
||||||
|
// These cannot change during play.
|
||||||
|
//("heightsec", p.heightsec)
|
||||||
|
//("bottommap", p.bottommap)
|
||||||
|
//("midmap", p.midmap)
|
||||||
|
//("topmap", p.topmap)
|
||||||
|
("damageamount", p.damageamount, def->damageamount)
|
||||||
|
("damageinterval", p.damageinterval, def->damageinterval)
|
||||||
|
("leakydamage", p.leakydamage, def->leakydamage)
|
||||||
|
("damagetype", p.damagetype, def->damagetype)
|
||||||
|
("sky", p.sky, def->sky)
|
||||||
|
("moreflags", p.MoreFlags, def->MoreFlags)
|
||||||
|
("flags", p.Flags, def->Flags)
|
||||||
|
.Array("portals", p.Portals, def->Portals, 2, true)
|
||||||
|
("zonenumber", p.ZoneNumber, def->ZoneNumber)
|
||||||
|
.Array("interpolations", p.interpolations, 4, true)
|
||||||
|
("soundtarget", p.SoundTarget)
|
||||||
|
("secacttarget", p.SecActTarget)
|
||||||
|
("floordata", p.floordata)
|
||||||
|
("ceilingdata", p.ceilingdata)
|
||||||
|
("lightingdata", p.lightingdata)
|
||||||
|
("fakefloor_sectors", p.e->FakeFloor.Sectors)
|
||||||
|
("midtexf_lines", p.e->Midtex.Floor.AttachedLines)
|
||||||
|
("midtexf_sectors", p.e->Midtex.Floor.AttachedSectors)
|
||||||
|
("midtexc_lines", p.e->Midtex.Ceiling.AttachedLines)
|
||||||
|
("midtexc_sectors", p.e->Midtex.Ceiling.AttachedSectors)
|
||||||
|
("linked_floor", p.e->Linked.Floor.Sectors)
|
||||||
|
("linked_ceiling", p.e->Linked.Ceiling.Sectors)
|
||||||
|
("colormap", p.ColorMap, def->ColorMap)
|
||||||
|
.Terrain("floorterrain", p.terrainnum[0], &def->terrainnum[0])
|
||||||
|
.Terrain("ceilingterrain", p.terrainnum[1], &def->terrainnum[1])
|
||||||
|
.EndObject();
|
||||||
|
}
|
||||||
|
return arc;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// RecalculateDrawnSubsectors
|
||||||
|
//
|
||||||
|
// In case the subsector data is unusable this function tries to reconstruct
|
||||||
|
// if from the linedefs' ML_MAPPED info.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void RecalculateDrawnSubsectors()
|
||||||
|
{
|
||||||
|
for (int i = 0; i<numsubsectors; i++)
|
||||||
|
{
|
||||||
|
subsector_t *sub = &subsectors[i];
|
||||||
|
for (unsigned int j = 0; j<sub->numlines; j++)
|
||||||
|
{
|
||||||
|
if (sub->firstline[j].linedef != NULL &&
|
||||||
|
(sub->firstline[j].linedef->flags & ML_MAPPED))
|
||||||
|
{
|
||||||
|
sub->flags |= SSECF_DRAWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
FSerializer &Serialize(FSerializer &arc, const char *key, subsector_t *&ss, subsector_t **)
|
||||||
|
{
|
||||||
|
BYTE by;
|
||||||
|
const char *str;
|
||||||
|
|
||||||
|
if (arc.isWriting())
|
||||||
|
{
|
||||||
|
if (hasglnodes)
|
||||||
|
{
|
||||||
|
TArray<char> encoded(1 + (numsubsectors + 5) / 6);
|
||||||
|
int p = 0;
|
||||||
|
for (int i = 0; i < numsubsectors; i += 6)
|
||||||
|
{
|
||||||
|
by = 0;
|
||||||
|
for (int j = 0; j < 6; j++)
|
||||||
|
{
|
||||||
|
if (i + j < numsubsectors && (subsectors[i + j].flags & SSECF_DRAWN))
|
||||||
|
{
|
||||||
|
by |= (1 << j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (by < 10) by += '0';
|
||||||
|
else if (by < 36) by += 'A' - 10;
|
||||||
|
else if (by < 62) by += 'a' - 36;
|
||||||
|
else if (by == 62) by = '-';
|
||||||
|
else if (by == 63) by = '+';
|
||||||
|
encoded[p++] = by;
|
||||||
|
}
|
||||||
|
encoded[p] = 0;
|
||||||
|
str = &encoded[0];
|
||||||
|
if (arc.BeginArray(key))
|
||||||
|
{
|
||||||
|
arc(nullptr, numvertexes)
|
||||||
|
(nullptr, numsubsectors)
|
||||||
|
.StringPtr(nullptr, str)
|
||||||
|
.EndArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int num_verts, num_subs;
|
||||||
|
bool success = false;
|
||||||
|
if (arc.BeginArray(key))
|
||||||
|
{
|
||||||
|
arc(nullptr, num_verts)
|
||||||
|
(nullptr, num_subs)
|
||||||
|
.StringPtr(nullptr, str)
|
||||||
|
.EndArray();
|
||||||
|
|
||||||
|
if (num_verts == numvertexes && num_subs == numsubsectors && hasglnodes)
|
||||||
|
{
|
||||||
|
success = true;
|
||||||
|
for (int i = 0; str[i] != 0; i++)
|
||||||
|
{
|
||||||
|
by = str[i];
|
||||||
|
if (by >= '0' && by <= '9') by -= '0';
|
||||||
|
else if (by >= 'A' && by <= 'Z') by -= 'A' - 10;
|
||||||
|
else if (by >= 'a' && by <= 'z') by -= 'a' - 36;
|
||||||
|
else if (by == '-') by = 62;
|
||||||
|
else if (by == '+') by = 63;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
success = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (hasglnodes && !success)
|
||||||
|
{
|
||||||
|
RecalculateDrawnSubsectors();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return arc;
|
||||||
|
}
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// Save a line portal for savegames.
|
||||||
|
//
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
FSerializer &Serialize(FSerializer &arc, const char *key, FLinePortal &port, FLinePortal *def)
|
||||||
|
{
|
||||||
|
if (arc.BeginObject(key))
|
||||||
|
{
|
||||||
|
arc("origin", port.mOrigin)
|
||||||
|
("destination", port.mDestination)
|
||||||
|
("displacement", port.mDisplacement)
|
||||||
|
("type", port.mType)
|
||||||
|
("flags", port.mFlags)
|
||||||
|
("defflags", port.mDefFlags)
|
||||||
|
("align", port.mAlign)
|
||||||
|
.EndObject();
|
||||||
|
}
|
||||||
|
return arc;
|
||||||
|
}
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// Save a sector portal for savegames.
|
||||||
|
//
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
FSerializer &Serialize(FSerializer &arc, const char *key, FSectorPortal &port, FSectorPortal *def)
|
||||||
|
{
|
||||||
|
if (arc.BeginObject(key))
|
||||||
|
{
|
||||||
|
arc("type", port.mType)
|
||||||
|
("flags", port.mFlags)
|
||||||
|
("partner", port.mPartner)
|
||||||
|
("plane", port.mPlane)
|
||||||
|
("origin", port.mOrigin)
|
||||||
|
("destination", port.mDestination)
|
||||||
|
("displacement", port.mDisplacement)
|
||||||
|
("planez", port.mPlaneZ)
|
||||||
|
("skybox", port.mSkybox)
|
||||||
|
.EndObject();
|
||||||
|
}
|
||||||
|
return arc;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
FSerializer &Serialize(FSerializer &arc, const char *key, ReverbContainer *&c, ReverbContainer **def)
|
||||||
|
{
|
||||||
|
int id = (arc.isReading() || c == nullptr) ? 0 : c->ID;
|
||||||
|
Serialize(arc, key, id, nullptr);
|
||||||
|
if (arc.isReading())
|
||||||
|
{
|
||||||
|
c = S_FindEnvironment(id);
|
||||||
|
}
|
||||||
|
return arc;
|
||||||
|
}
|
||||||
|
|
||||||
|
FSerializer &Serialize(FSerializer &arc, const char *key, zone_t &z, zone_t *def)
|
||||||
|
{
|
||||||
|
return Serialize(arc, key, z.Environment, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
void SerializeWorld(FSerializer &arc)
|
||||||
|
{
|
||||||
|
// fixme: This needs to ensure it reads from the correct place. Should be one once there's enough of this code converted to JSON
|
||||||
|
arc.Array("linedefs", lines, &loadlines[0], numlines)
|
||||||
|
.Array("sidedefs", sides, &loadsides[0], numsides)
|
||||||
|
.Array("sectors", sectors, &loadsectors[0], numsectors)
|
||||||
|
("subsectors", subsectors)
|
||||||
|
("zones", Zones)
|
||||||
|
("lineportals", linePortals)
|
||||||
|
("sectorportals", sectorPortals);
|
||||||
|
|
||||||
|
if (arc.isReading()) P_CollectLinkedPortals();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// ArchiveSounds
|
// ArchiveSounds
|
||||||
|
@ -625,96 +862,132 @@ void P_SerializePolyobjs (FArchive &arc)
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// RecalculateDrawnSubsectors
|
|
||||||
//
|
|
||||||
// In case the subsector data is unusable this function tries to reconstruct
|
|
||||||
// if from the linedefs' ML_MAPPED info.
|
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void RecalculateDrawnSubsectors()
|
void G_SerializeLevel(FArchive &arc, bool hubLoad)
|
||||||
{
|
{
|
||||||
for(int i=0;i<numsubsectors;i++)
|
int i = level.totaltime;
|
||||||
|
|
||||||
|
unsigned tm = I_MSTime();
|
||||||
|
|
||||||
|
Renderer->StartSerialize(arc);
|
||||||
|
if (arc.IsLoading()) P_DestroyThinkers(hubLoad);
|
||||||
|
|
||||||
|
arc << level.flags
|
||||||
|
<< level.flags2
|
||||||
|
<< level.fadeto
|
||||||
|
<< level.found_secrets
|
||||||
|
<< level.found_items
|
||||||
|
<< level.killed_monsters
|
||||||
|
<< level.gravity
|
||||||
|
<< level.aircontrol
|
||||||
|
<< level.teamdamage
|
||||||
|
<< level.maptime
|
||||||
|
<< i;
|
||||||
|
|
||||||
|
// Hub transitions must keep the current total time
|
||||||
|
if (!hubLoad)
|
||||||
|
level.totaltime = i;
|
||||||
|
|
||||||
|
arc << level.skytexture1 << level.skytexture2;
|
||||||
|
if (arc.IsLoading())
|
||||||
{
|
{
|
||||||
subsector_t *sub = &subsectors[i];
|
sky1texture = level.skytexture1;
|
||||||
for(unsigned int j=0;j<sub->numlines;j++)
|
sky2texture = level.skytexture2;
|
||||||
{
|
R_InitSkyMap();
|
||||||
if (sub->firstline[j].linedef != NULL &&
|
|
||||||
(sub->firstline[j].linedef->flags & ML_MAPPED))
|
|
||||||
{
|
|
||||||
sub->flags |= SSECF_DRAWN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
G_AirControlChanged();
|
||||||
//
|
|
||||||
// ArchiveSubsectors
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void P_SerializeSubsectors(FArchive &arc)
|
BYTE t;
|
||||||
{
|
|
||||||
int num_verts, num_subs, num_nodes;
|
|
||||||
BYTE by;
|
|
||||||
|
|
||||||
|
// Does this level have scrollers?
|
||||||
if (arc.IsStoring())
|
if (arc.IsStoring())
|
||||||
{
|
{
|
||||||
if (hasglnodes)
|
t = level.Scrolls ? 1 : 0;
|
||||||
{
|
arc << t;
|
||||||
arc << numvertexes << numsubsectors << numnodes; // These are only for verification
|
|
||||||
for(int i=0;i<numsubsectors;i+=8)
|
|
||||||
{
|
|
||||||
by = 0;
|
|
||||||
for(int j=0;j<8;j++)
|
|
||||||
{
|
|
||||||
if (i+j<numsubsectors && (subsectors[i+j].flags & SSECF_DRAWN))
|
|
||||||
{
|
|
||||||
by |= (1<<j);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
arc << by;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int v = 0;
|
|
||||||
arc << v << v << v;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
arc << num_verts << num_subs << num_nodes;
|
arc << t;
|
||||||
if (num_verts != numvertexes ||
|
if (level.Scrolls)
|
||||||
num_subs != numsubsectors ||
|
|
||||||
num_nodes != numnodes)
|
|
||||||
{
|
{
|
||||||
// Nodes don't match - we can't use this info
|
delete[] level.Scrolls;
|
||||||
for(int i=0;i<num_subs;i+=8)
|
level.Scrolls = NULL;
|
||||||
{
|
|
||||||
// Skip the subsector info.
|
|
||||||
arc << by;
|
|
||||||
}
|
|
||||||
if (hasglnodes)
|
|
||||||
{
|
|
||||||
RecalculateDrawnSubsectors();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
else
|
if (t)
|
||||||
{
|
{
|
||||||
for(int i=0;i<numsubsectors;i+=8)
|
level.Scrolls = new FSectorScrollValues[numsectors];
|
||||||
|
memset(level.Scrolls, 0, sizeof(level.Scrolls)*numsectors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FBehavior::StaticSerializeModuleStates(arc);
|
||||||
|
if (arc.IsLoading()) interpolator.ClearInterpolations();
|
||||||
|
P_SerializeWorld(arc);
|
||||||
|
P_SerializeThinkers(arc, hubLoad);
|
||||||
|
P_SerializeWorldActors(arc); // serializing actor pointers in the world data must be done after SerializeWorld has restored the entire sector state, otherwise LinkToWorld may fail.
|
||||||
|
P_SerializePolyobjs(arc);
|
||||||
|
P_SerializeSubsectors(arc);
|
||||||
|
StatusBar->Serialize(arc);
|
||||||
|
|
||||||
|
arc << level.total_monsters << level.total_items << level.total_secrets;
|
||||||
|
|
||||||
|
// Does this level have custom translations?
|
||||||
|
FRemapTable *trans;
|
||||||
|
WORD w;
|
||||||
|
if (arc.IsStoring())
|
||||||
|
{
|
||||||
|
for (unsigned int i = 0; i < translationtables[TRANSLATION_LevelScripted].Size(); ++i)
|
||||||
|
{
|
||||||
|
trans = translationtables[TRANSLATION_LevelScripted][i];
|
||||||
|
if (trans != NULL && !trans->IsIdentity())
|
||||||
{
|
{
|
||||||
arc << by;
|
w = WORD(i);
|
||||||
for(int j=0;j<8;j++)
|
arc << w;
|
||||||
{
|
trans->Serialize(arc);
|
||||||
if ((by & (1<<j)) && i+j<numsubsectors)
|
}
|
||||||
{
|
}
|
||||||
subsectors[i+j].flags |= SSECF_DRAWN;
|
w = 0xffff;
|
||||||
}
|
arc << w;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (arc << w, w != 0xffff)
|
||||||
|
{
|
||||||
|
trans = translationtables[TRANSLATION_LevelScripted].GetVal(w);
|
||||||
|
if (trans == NULL)
|
||||||
|
{
|
||||||
|
trans = new FRemapTable;
|
||||||
|
translationtables[TRANSLATION_LevelScripted].SetVal(w, trans);
|
||||||
|
}
|
||||||
|
trans->Serialize(arc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This must be saved, too, of course!
|
||||||
|
FCanvasTextureInfo::Serialize(arc);
|
||||||
|
AM_SerializeMarkers(arc);
|
||||||
|
|
||||||
|
P_SerializePlayers(arc, hubLoad);
|
||||||
|
P_SerializeSounds(arc);
|
||||||
|
if (arc.IsLoading())
|
||||||
|
{
|
||||||
|
for (i = 0; i < numsectors; i++)
|
||||||
|
{
|
||||||
|
P_Recalculate3DFloors(§ors[i]);
|
||||||
|
}
|
||||||
|
for (i = 0; i < MAXPLAYERS; ++i)
|
||||||
|
{
|
||||||
|
if (playeringame[i] && players[i].mo != NULL)
|
||||||
|
{
|
||||||
|
players[i].mo->SetupWeaponSlots();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Renderer->EndSerialize(arc);
|
||||||
|
unsigned tt = I_MSTime();
|
||||||
|
Printf("Serialization took %d ms\n", tt - tm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,4 +52,6 @@ void P_SerializeSounds (FArchive &arc);
|
||||||
void P_ReadACSDefereds (PNGHandle *png);
|
void P_ReadACSDefereds (PNGHandle *png);
|
||||||
void P_WriteACSDefereds (FILE *file);
|
void P_WriteACSDefereds (FILE *file);
|
||||||
|
|
||||||
|
void G_SerializeLevel(FArchive &arc, bool hubLoad);
|
||||||
|
|
||||||
#endif // __P_SAVEG_H__
|
#endif // __P_SAVEG_H__
|
||||||
|
|
|
@ -47,71 +47,6 @@
|
||||||
// actor. States are archived by recording the actor they belong
|
// actor. States are archived by recording the actor they belong
|
||||||
// to and the index into that actor's list of states.
|
// to and the index into that actor's list of states.
|
||||||
|
|
||||||
// For NULL states, which aren't owned by any actor, the owner
|
|
||||||
// is recorded as AActor with the following state. AActor should
|
|
||||||
// never actually have this many states of its own, so this
|
|
||||||
// is (relatively) safe.
|
|
||||||
|
|
||||||
#define NULL_STATE_INDEX 127
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
FArchive &operator<< (FArchive &arc, FState *&state)
|
|
||||||
{
|
|
||||||
PClassActor *info;
|
|
||||||
|
|
||||||
if (arc.IsStoring ())
|
|
||||||
{
|
|
||||||
if (state == NULL)
|
|
||||||
{
|
|
||||||
arc.UserWriteClass (RUNTIME_CLASS(AActor));
|
|
||||||
arc.WriteCount (NULL_STATE_INDEX);
|
|
||||||
return arc;
|
|
||||||
}
|
|
||||||
|
|
||||||
info = FState::StaticFindStateOwner (state);
|
|
||||||
|
|
||||||
if (info != NULL)
|
|
||||||
{
|
|
||||||
arc.UserWriteClass (info);
|
|
||||||
arc.WriteCount ((DWORD)(state - info->OwnedStates));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* this was never working as intended.
|
|
||||||
I_Error ("Cannot find owner for state %p:\n"
|
|
||||||
"%s %c%c %3d [%p] -> %p", state,
|
|
||||||
sprites[state->sprite].name,
|
|
||||||
state->GetFrame() + 'A',
|
|
||||||
state->GetFullbright() ? '*' : ' ',
|
|
||||||
state->GetTics(),
|
|
||||||
state->GetAction(),
|
|
||||||
state->GetNextState());
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PClassActor *info;
|
|
||||||
DWORD ofs;
|
|
||||||
|
|
||||||
arc.UserReadClass<PClassActor>(info);
|
|
||||||
ofs = arc.ReadCount ();
|
|
||||||
if (ofs == NULL_STATE_INDEX && info == RUNTIME_CLASS(AActor))
|
|
||||||
{
|
|
||||||
state = NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
state = info->OwnedStates + ofs;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return arc;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// Find the actor that a state belongs to.
|
// Find the actor that a state belongs to.
|
||||||
|
|
|
@ -504,7 +504,9 @@ void FSerializer::WriteObjects()
|
||||||
BeginObject(nullptr);
|
BeginObject(nullptr);
|
||||||
WriteKey("classtype");
|
WriteKey("classtype");
|
||||||
w->mWriter.String(w->mDObjects[i]->GetClass()->TypeName.GetChars());
|
w->mWriter.String(w->mDObjects[i]->GetClass()->TypeName.GetChars());
|
||||||
|
w->mDObjects[i]->SerializeUserVars(*this);
|
||||||
w->mDObjects[i]->Serialize(*this);
|
w->mDObjects[i]->Serialize(*this);
|
||||||
|
w->mDObjects[i]->CheckIfSerialized();
|
||||||
EndObject();
|
EndObject();
|
||||||
}
|
}
|
||||||
EndArray();
|
EndArray();
|
||||||
|
@ -1144,8 +1146,18 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FState *&state, FState
|
||||||
}
|
}
|
||||||
else if (val->IsArray())
|
else if (val->IsArray())
|
||||||
{
|
{
|
||||||
//rapidjson::Value cls = (*val)[0];
|
const rapidjson::Value &cls = (*val)[0];
|
||||||
//rapidjson::Value ndx = (*val)[1];
|
const rapidjson::Value &ndx = (*val)[1];
|
||||||
|
|
||||||
|
state = nullptr;
|
||||||
|
if (cls.IsString() && ndx.IsInt())
|
||||||
|
{
|
||||||
|
PClassActor *clas = PClass::FindActor(cls.GetString());
|
||||||
|
if (clas)
|
||||||
|
{
|
||||||
|
state = clas->OwnedStates + ndx.GetInt();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
697
src/zzz_old.cpp
Normal file
697
src/zzz_old.cpp
Normal file
|
@ -0,0 +1,697 @@
|
||||||
|
// For NULL states, which aren't owned by any actor, the owner
|
||||||
|
// is recorded as AActor with the following state. AActor should
|
||||||
|
// never actually have this many states of its own, so this
|
||||||
|
// is (relatively) safe.
|
||||||
|
|
||||||
|
#define NULL_STATE_INDEX 127
|
||||||
|
|
||||||
|
// These are special tokens found in the data stream of an archive.
|
||||||
|
// Whenever a new object is encountered, it gets created using new and
|
||||||
|
// is then asked to serialize itself before processing of the previous
|
||||||
|
// object continues. This can result in some very deep recursion if
|
||||||
|
// you aren't careful about how you organize your data.
|
||||||
|
|
||||||
|
#define NEW_OBJ ((BYTE)1) // Data for a new object follows
|
||||||
|
#define NEW_CLS_OBJ ((BYTE)2) // Data for a new class and object follows
|
||||||
|
#define OLD_OBJ ((BYTE)3) // Reference to an old object follows
|
||||||
|
#define NULL_OBJ ((BYTE)4) // Load as NULL
|
||||||
|
#define M1_OBJ ((BYTE)44) // Load as (DObject*)-1
|
||||||
|
|
||||||
|
#define NEW_PLYR_OBJ ((BYTE)5) // Data for a new player follows
|
||||||
|
#define NEW_PLYR_CLS_OBJ ((BYTE)6) // Data for a new class and player follows
|
||||||
|
|
||||||
|
#define NEW_NAME ((BYTE)27) // A new name follows
|
||||||
|
#define OLD_NAME ((BYTE)28) // Reference to an old name follows
|
||||||
|
#define NIL_NAME ((BYTE)33) // Load as NULL
|
||||||
|
|
||||||
|
#define NEW_SPRITE ((BYTE)11) // A new sprite name follows
|
||||||
|
#define OLD_SPRITE ((BYTE)12) // Reference to an old sprite name follows
|
||||||
|
|
||||||
|
inline FArchive &operator<< (FArchive &arc, FLinkedSector &link)
|
||||||
|
{
|
||||||
|
arc << link.Sector << link.Type;
|
||||||
|
return arc;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// P_ArchiveWorld
|
||||||
|
//
|
||||||
|
void P_SerializeWorld (FArchive &arc)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
sector_t *sec;
|
||||||
|
line_t *li;
|
||||||
|
zone_t *zn;
|
||||||
|
|
||||||
|
// do sectors
|
||||||
|
for (i = 0, sec = sectors; i < numsectors; i++, sec++)
|
||||||
|
{
|
||||||
|
arc << sec->floorplane
|
||||||
|
<< sec->ceilingplane;
|
||||||
|
arc << sec->lightlevel;
|
||||||
|
arc << sec->special;
|
||||||
|
arc << sec->soundtraversed
|
||||||
|
<< sec->seqType
|
||||||
|
<< sec->friction
|
||||||
|
<< sec->movefactor
|
||||||
|
<< sec->stairlock
|
||||||
|
<< sec->prevsec
|
||||||
|
<< sec->nextsec
|
||||||
|
<< sec->planes[sector_t::floor]
|
||||||
|
<< sec->planes[sector_t::ceiling]
|
||||||
|
<< sec->heightsec
|
||||||
|
<< sec->bottommap << sec->midmap << sec->topmap
|
||||||
|
<< sec->gravity;
|
||||||
|
P_SerializeTerrain(arc, sec->terrainnum[0]);
|
||||||
|
P_SerializeTerrain(arc, sec->terrainnum[1]);
|
||||||
|
arc << sec->damageamount;
|
||||||
|
arc << sec->damageinterval
|
||||||
|
<< sec->leakydamage
|
||||||
|
<< sec->damagetype
|
||||||
|
<< sec->sky
|
||||||
|
<< sec->MoreFlags
|
||||||
|
<< sec->Flags
|
||||||
|
<< sec->Portals[sector_t::floor] << sec->Portals[sector_t::ceiling]
|
||||||
|
<< sec->ZoneNumber;
|
||||||
|
arc << sec->interpolations[0]
|
||||||
|
<< sec->interpolations[1]
|
||||||
|
<< sec->interpolations[2]
|
||||||
|
<< sec->interpolations[3]
|
||||||
|
<< sec->SeqName;
|
||||||
|
|
||||||
|
sec->e->Serialize(arc);
|
||||||
|
if (arc.IsStoring ())
|
||||||
|
{
|
||||||
|
arc << sec->ColorMap->Color
|
||||||
|
<< sec->ColorMap->Fade;
|
||||||
|
BYTE sat = sec->ColorMap->Desaturate;
|
||||||
|
arc << sat;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PalEntry color, fade;
|
||||||
|
BYTE desaturate;
|
||||||
|
arc << color << fade
|
||||||
|
<< desaturate;
|
||||||
|
sec->ColorMap = GetSpecialLights (color, fade, desaturate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// do lines
|
||||||
|
for (i = 0, li = lines; i < numlines; i++, li++)
|
||||||
|
{
|
||||||
|
arc << li->flags
|
||||||
|
<< li->activation
|
||||||
|
<< li->special
|
||||||
|
<< li->alpha;
|
||||||
|
|
||||||
|
if (P_IsACSSpecial(li->special))
|
||||||
|
{
|
||||||
|
P_SerializeACSScriptNumber(arc, li->args[0], false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
arc << li->args[0];
|
||||||
|
}
|
||||||
|
arc << li->args[1] << li->args[2] << li->args[3] << li->args[4];
|
||||||
|
|
||||||
|
arc << li->portalindex;
|
||||||
|
for (j = 0; j < 2; j++)
|
||||||
|
{
|
||||||
|
if (li->sidedef[j] == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
side_t *si = li->sidedef[j];
|
||||||
|
arc << si->textures[side_t::top]
|
||||||
|
<< si->textures[side_t::mid]
|
||||||
|
<< si->textures[side_t::bottom]
|
||||||
|
<< si->Light
|
||||||
|
<< si->Flags
|
||||||
|
<< si->LeftSide
|
||||||
|
<< si->RightSide
|
||||||
|
<< si->Index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// do zones
|
||||||
|
unsigned numzones = Zones.Size();
|
||||||
|
arc << numzones;
|
||||||
|
|
||||||
|
if (arc.IsLoading())
|
||||||
|
{
|
||||||
|
Zones.Resize(numzones);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0, zn = &Zones[0]; i < (int)numzones; ++i, ++zn)
|
||||||
|
{
|
||||||
|
arc << zn->Environment;
|
||||||
|
}
|
||||||
|
|
||||||
|
arc << linePortals << sectorPortals;
|
||||||
|
P_CollectLinkedPortals();
|
||||||
|
}
|
||||||
|
|
||||||
|
void P_SerializeWorldActors(FArchive &arc)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
sector_t *sec;
|
||||||
|
line_t *line;
|
||||||
|
|
||||||
|
for (i = 0, sec = sectors; i < numsectors; i++, sec++)
|
||||||
|
{
|
||||||
|
arc << sec->SoundTarget
|
||||||
|
<< sec->SecActTarget
|
||||||
|
<< sec->floordata
|
||||||
|
<< sec->ceilingdata
|
||||||
|
<< sec->lightingdata;
|
||||||
|
}
|
||||||
|
for (auto &s : sectorPortals)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
arc << FakeFloor.Sectors
|
||||||
|
<< Midtex.Floor.AttachedLines
|
||||||
|
<< Midtex.Floor.AttachedSectors
|
||||||
|
<< Midtex.Ceiling.AttachedLines
|
||||||
|
<< Midtex.Ceiling.AttachedSectors
|
||||||
|
<< Linked.Floor.Sectors
|
||||||
|
<< Linked.Ceiling.Sectors;
|
||||||
|
}
|
||||||
|
|
||||||
|
FArchive &operator<< (FArchive &arc, side_t::part &p)
|
||||||
|
{
|
||||||
|
arc << p.xOffset << p.yOffset << p.interpolation << p.texture
|
||||||
|
<< p.xScale << p.yScale;// << p.Light;
|
||||||
|
return arc;
|
||||||
|
}
|
||||||
|
|
||||||
|
FArchive &operator<< (FArchive &arc, sector_t::splane &p)
|
||||||
|
{
|
||||||
|
arc << p.xform.xOffs << p.xform.yOffs << p.xform.xScale << p.xform.yScale
|
||||||
|
<< p.xform.Angle << p.xform.baseyOffs << p.xform.baseAngle
|
||||||
|
<< p.Flags << p.Light << p.Texture << p.TexZ << p.alpha;
|
||||||
|
return arc;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// ArchiveSubsectors
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
void RecalculateDrawnSubsectors();
|
||||||
|
|
||||||
|
void P_SerializeSubsectors(FArchive &arc)
|
||||||
|
{
|
||||||
|
int num_verts, num_subs, num_nodes;
|
||||||
|
BYTE by;
|
||||||
|
|
||||||
|
if (arc.IsStoring())
|
||||||
|
{
|
||||||
|
if (hasglnodes)
|
||||||
|
{
|
||||||
|
arc << numvertexes << numsubsectors << numnodes; // These are only for verification
|
||||||
|
for(int i=0;i<numsubsectors;i+=8)
|
||||||
|
{
|
||||||
|
by = 0;
|
||||||
|
for(int j=0;j<8;j++)
|
||||||
|
{
|
||||||
|
if (i+j<numsubsectors && (subsectors[i+j].flags & SSECF_DRAWN))
|
||||||
|
{
|
||||||
|
by |= (1<<j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
arc << by;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int v = 0;
|
||||||
|
arc << v << v << v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
arc << num_verts << num_subs << num_nodes;
|
||||||
|
if (num_verts != numvertexes ||
|
||||||
|
num_subs != numsubsectors ||
|
||||||
|
num_nodes != numnodes)
|
||||||
|
{
|
||||||
|
// Nodes don't match - we can't use this info
|
||||||
|
for(int i=0;i<num_subs;i+=8)
|
||||||
|
{
|
||||||
|
// Skip the subsector info.
|
||||||
|
arc << by;
|
||||||
|
}
|
||||||
|
if (hasglnodes)
|
||||||
|
{
|
||||||
|
RecalculateDrawnSubsectors();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(int i=0;i<numsubsectors;i+=8)
|
||||||
|
{
|
||||||
|
arc << by;
|
||||||
|
for(int j=0;j<8;j++)
|
||||||
|
{
|
||||||
|
if ((by & (1<<j)) && i+j<numsubsectors)
|
||||||
|
{
|
||||||
|
subsectors[i+j].flags |= SSECF_DRAWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FArchive &FArchive::WriteObject (DObject *obj)
|
||||||
|
{
|
||||||
|
player_t *player;
|
||||||
|
BYTE id[2];
|
||||||
|
|
||||||
|
if (obj == NULL)
|
||||||
|
{
|
||||||
|
id[0] = NULL_OBJ;
|
||||||
|
Write (id, 1);
|
||||||
|
}
|
||||||
|
else if (obj == (DObject*)~0)
|
||||||
|
{
|
||||||
|
id[0] = M1_OBJ;
|
||||||
|
Write (id, 1);
|
||||||
|
}
|
||||||
|
else if (obj->ObjectFlags & OF_EuthanizeMe)
|
||||||
|
{
|
||||||
|
// Objects that want to die are not saved to the archive, but
|
||||||
|
// we leave the pointers to them alone.
|
||||||
|
id[0] = NULL_OBJ;
|
||||||
|
Write (id, 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PClass *type = obj->GetClass();
|
||||||
|
DWORD *classarcid;
|
||||||
|
|
||||||
|
if (type == RUNTIME_CLASS(DObject))
|
||||||
|
{
|
||||||
|
//I_Error ("Tried to save an instance of DObject.\n"
|
||||||
|
// "This should not happen.\n");
|
||||||
|
id[0] = NULL_OBJ;
|
||||||
|
Write (id, 1);
|
||||||
|
}
|
||||||
|
else if (NULL == (classarcid = ClassToArchive.CheckKey(type)))
|
||||||
|
{
|
||||||
|
// No instances of this class have been written out yet.
|
||||||
|
// Write out the class, then write out the object. If this
|
||||||
|
// is an actor controlled by a player, make note of that
|
||||||
|
// so that it can be overridden when moving around in a hub.
|
||||||
|
if (obj->IsKindOf (RUNTIME_CLASS (AActor)) &&
|
||||||
|
(player = static_cast<AActor *>(obj)->player) &&
|
||||||
|
player->mo == obj)
|
||||||
|
{
|
||||||
|
id[0] = NEW_PLYR_CLS_OBJ;
|
||||||
|
id[1] = (BYTE)(player - players);
|
||||||
|
Write (id, 2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
id[0] = NEW_CLS_OBJ;
|
||||||
|
Write (id, 1);
|
||||||
|
}
|
||||||
|
WriteClass (type);
|
||||||
|
// Printf ("Make class %s (%u)\n", type->Name, m_File->Tell());
|
||||||
|
MapObject (obj);
|
||||||
|
obj->SerializeUserVars (*this);
|
||||||
|
obj->Serialize (*this);
|
||||||
|
obj->CheckIfSerialized ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// An instance of this class has already been saved. If
|
||||||
|
// this object has already been written, save a reference
|
||||||
|
// to the saved object. Otherwise, save a reference to the
|
||||||
|
// class, then save the object. Again, if this is a player-
|
||||||
|
// controlled actor, remember that.
|
||||||
|
DWORD *objarcid = ObjectToArchive.CheckKey(obj);
|
||||||
|
|
||||||
|
if (objarcid == NULL)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (obj->IsKindOf (RUNTIME_CLASS (AActor)) &&
|
||||||
|
(player = static_cast<AActor *>(obj)->player) &&
|
||||||
|
player->mo == obj)
|
||||||
|
{
|
||||||
|
id[0] = NEW_PLYR_OBJ;
|
||||||
|
id[1] = (BYTE)(player - players);
|
||||||
|
Write (id, 2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
id[0] = NEW_OBJ;
|
||||||
|
Write (id, 1);
|
||||||
|
}
|
||||||
|
WriteCount (*classarcid);
|
||||||
|
// Printf ("Reuse class %s (%u)\n", type->Name, m_File->Tell());
|
||||||
|
MapObject (obj);
|
||||||
|
obj->SerializeUserVars (*this);
|
||||||
|
obj->Serialize (*this);
|
||||||
|
obj->CheckIfSerialized ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
id[0] = OLD_OBJ;
|
||||||
|
Write (id, 1);
|
||||||
|
WriteCount (*objarcid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AActor::Serialize(FArchive &arc)
|
||||||
|
{
|
||||||
|
Super::Serialize(arc);
|
||||||
|
|
||||||
|
if (arc.IsStoring())
|
||||||
|
{
|
||||||
|
arc.WriteSprite(sprite);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sprite = arc.ReadSprite();
|
||||||
|
}
|
||||||
|
|
||||||
|
arc << __Pos
|
||||||
|
<< Angles.Yaw
|
||||||
|
<< Angles.Pitch
|
||||||
|
<< Angles.Roll
|
||||||
|
<< frame
|
||||||
|
<< Scale
|
||||||
|
<< RenderStyle
|
||||||
|
<< renderflags
|
||||||
|
<< picnum
|
||||||
|
<< floorpic
|
||||||
|
<< ceilingpic
|
||||||
|
<< TIDtoHate
|
||||||
|
<< LastLookPlayerNumber
|
||||||
|
<< LastLookActor
|
||||||
|
<< effects
|
||||||
|
<< Alpha
|
||||||
|
<< fillcolor
|
||||||
|
<< Sector
|
||||||
|
<< floorz
|
||||||
|
<< ceilingz
|
||||||
|
<< dropoffz
|
||||||
|
<< floorsector
|
||||||
|
<< ceilingsector
|
||||||
|
<< radius
|
||||||
|
<< Height
|
||||||
|
<< projectilepassheight
|
||||||
|
<< Vel
|
||||||
|
<< tics
|
||||||
|
<< state
|
||||||
|
<< DamageVal;
|
||||||
|
if (DamageVal == 0x40000000 || DamageVal == -1)
|
||||||
|
{
|
||||||
|
DamageVal = -1;
|
||||||
|
DamageFunc = GetDefault()->DamageFunc;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DamageFunc = nullptr;
|
||||||
|
}
|
||||||
|
P_SerializeTerrain(arc, floorterrain);
|
||||||
|
arc << projectileKickback
|
||||||
|
<< flags
|
||||||
|
<< flags2
|
||||||
|
<< flags3
|
||||||
|
<< flags4
|
||||||
|
<< flags5
|
||||||
|
<< flags6
|
||||||
|
<< flags7
|
||||||
|
<< weaponspecial
|
||||||
|
<< special1
|
||||||
|
<< special2
|
||||||
|
<< specialf1
|
||||||
|
<< specialf2
|
||||||
|
<< health
|
||||||
|
<< movedir
|
||||||
|
<< visdir
|
||||||
|
<< movecount
|
||||||
|
<< strafecount
|
||||||
|
<< target
|
||||||
|
<< lastenemy
|
||||||
|
<< LastHeard
|
||||||
|
<< reactiontime
|
||||||
|
<< threshold
|
||||||
|
<< player
|
||||||
|
<< SpawnPoint
|
||||||
|
<< SpawnAngle
|
||||||
|
<< StartHealth
|
||||||
|
<< skillrespawncount
|
||||||
|
<< tracer
|
||||||
|
<< Floorclip
|
||||||
|
<< tid
|
||||||
|
<< special;
|
||||||
|
if (P_IsACSSpecial(special))
|
||||||
|
{
|
||||||
|
P_SerializeACSScriptNumber(arc, args[0], false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
arc << args[0];
|
||||||
|
}
|
||||||
|
arc << args[1] << args[2] << args[3] << args[4];
|
||||||
|
arc << accuracy << stamina;
|
||||||
|
arc << goal
|
||||||
|
<< waterlevel
|
||||||
|
<< MinMissileChance
|
||||||
|
<< SpawnFlags
|
||||||
|
<< Inventory
|
||||||
|
<< InventoryID;
|
||||||
|
arc << FloatBobPhase
|
||||||
|
<< Translation
|
||||||
|
<< SeeSound
|
||||||
|
<< AttackSound
|
||||||
|
<< PainSound
|
||||||
|
<< DeathSound
|
||||||
|
<< ActiveSound
|
||||||
|
<< UseSound
|
||||||
|
<< BounceSound
|
||||||
|
<< WallBounceSound
|
||||||
|
<< CrushPainSound
|
||||||
|
<< Speed
|
||||||
|
<< FloatSpeed
|
||||||
|
<< Mass
|
||||||
|
<< PainChance
|
||||||
|
<< SpawnState
|
||||||
|
<< SeeState
|
||||||
|
<< MeleeState
|
||||||
|
<< MissileState
|
||||||
|
<< MaxDropOffHeight
|
||||||
|
<< MaxStepHeight
|
||||||
|
<< BounceFlags
|
||||||
|
<< bouncefactor
|
||||||
|
<< wallbouncefactor
|
||||||
|
<< bouncecount
|
||||||
|
<< maxtargetrange
|
||||||
|
<< meleethreshold
|
||||||
|
<< meleerange
|
||||||
|
<< DamageType;
|
||||||
|
arc << DamageTypeReceived;
|
||||||
|
arc << PainType
|
||||||
|
<< DeathType;
|
||||||
|
arc << Gravity
|
||||||
|
<< FastChaseStrafeCount
|
||||||
|
<< master
|
||||||
|
<< smokecounter
|
||||||
|
<< BlockingMobj
|
||||||
|
<< BlockingLine
|
||||||
|
<< VisibleToTeam // [BB]
|
||||||
|
<< pushfactor
|
||||||
|
<< Species
|
||||||
|
<< Score;
|
||||||
|
arc << DesignatedTeam;
|
||||||
|
arc << lastpush << lastbump
|
||||||
|
<< PainThreshold
|
||||||
|
<< DamageFactor;
|
||||||
|
arc << DamageMultiply;
|
||||||
|
arc << WeaveIndexXY << WeaveIndexZ
|
||||||
|
<< PoisonDamageReceived << PoisonDurationReceived << PoisonPeriodReceived << Poisoner
|
||||||
|
<< PoisonDamage << PoisonDuration << PoisonPeriod;
|
||||||
|
arc << PoisonDamageType << PoisonDamageTypeReceived;
|
||||||
|
arc << ConversationRoot << Conversation;
|
||||||
|
arc << FriendPlayer;
|
||||||
|
arc << TeleFogSourceType
|
||||||
|
<< TeleFogDestType;
|
||||||
|
arc << RipperLevel
|
||||||
|
<< RipLevelMin
|
||||||
|
<< RipLevelMax;
|
||||||
|
arc << DefThreshold;
|
||||||
|
if (SaveVersion >= 4549)
|
||||||
|
{
|
||||||
|
arc << SpriteAngle;
|
||||||
|
arc << SpriteRotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SaveVersion >= 4550)
|
||||||
|
{
|
||||||
|
arc << alternative;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
FString tagstr;
|
||||||
|
if (arc.IsStoring() && Tag != NULL && Tag->Len() > 0) tagstr = *Tag;
|
||||||
|
arc << tagstr;
|
||||||
|
if (arc.IsLoading())
|
||||||
|
{
|
||||||
|
if (tagstr.Len() == 0) Tag = NULL;
|
||||||
|
else Tag = mStringPropertyData.Alloc(tagstr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arc.IsLoading ())
|
||||||
|
{
|
||||||
|
touching_sectorlist = NULL;
|
||||||
|
LinkToWorld(false, Sector);
|
||||||
|
|
||||||
|
AddToHash ();
|
||||||
|
SetShade (fillcolor);
|
||||||
|
if (player)
|
||||||
|
{
|
||||||
|
if (playeringame[player - players] &&
|
||||||
|
player->cls != NULL &&
|
||||||
|
!(flags4 & MF4_NOSKIN) &&
|
||||||
|
state->sprite == GetDefaultByType (player->cls)->SpawnState->sprite)
|
||||||
|
{ // Give player back the skin
|
||||||
|
sprite = skins[player->userinfo.GetSkin()].sprite;
|
||||||
|
}
|
||||||
|
if (Speed == 0)
|
||||||
|
{
|
||||||
|
Speed = GetDefault()->Speed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ClearInterpolation();
|
||||||
|
UpdateWaterLevel(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FArchive &operator<< (FArchive &arc, sector_t *&sec)
|
||||||
|
{
|
||||||
|
return arc.SerializePointer (sectors, (BYTE **)&sec, sizeof(*sectors));
|
||||||
|
}
|
||||||
|
|
||||||
|
FArchive &operator<< (FArchive &arc, const sector_t *&sec)
|
||||||
|
{
|
||||||
|
return arc.SerializePointer (sectors, (BYTE **)&sec, sizeof(*sectors));
|
||||||
|
}
|
||||||
|
|
||||||
|
FArchive &operator<< (FArchive &arc, line_t *&line)
|
||||||
|
{
|
||||||
|
return arc.SerializePointer (lines, (BYTE **)&line, sizeof(*lines));
|
||||||
|
}
|
||||||
|
|
||||||
|
FArchive &operator<< (FArchive &arc, vertex_t *&vert)
|
||||||
|
{
|
||||||
|
return arc.SerializePointer (vertexes, (BYTE **)&vert, sizeof(*vertexes));
|
||||||
|
}
|
||||||
|
|
||||||
|
FArchive &operator<< (FArchive &arc, side_t *&side)
|
||||||
|
{
|
||||||
|
return arc.SerializePointer (sides, (BYTE **)&side, sizeof(*sides));
|
||||||
|
}
|
||||||
|
|
||||||
|
FArchive &operator<<(FArchive &arc, DAngle &ang)
|
||||||
|
{
|
||||||
|
arc << ang.Degrees;
|
||||||
|
return arc;
|
||||||
|
}
|
||||||
|
|
||||||
|
FArchive &operator<<(FArchive &arc, DVector3 &vec)
|
||||||
|
{
|
||||||
|
arc << vec.X << vec.Y << vec.Z;
|
||||||
|
return arc;
|
||||||
|
}
|
||||||
|
|
||||||
|
FArchive &operator<<(FArchive &arc, DVector2 &vec)
|
||||||
|
{
|
||||||
|
arc << vec.X << vec.Y;
|
||||||
|
return arc;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
FArchive &operator<< (FArchive &arc, FState *&state)
|
||||||
|
{
|
||||||
|
PClassActor *info;
|
||||||
|
|
||||||
|
if (arc.IsStoring ())
|
||||||
|
{
|
||||||
|
if (state == NULL)
|
||||||
|
{
|
||||||
|
arc.UserWriteClass (RUNTIME_CLASS(AActor));
|
||||||
|
arc.WriteCount (NULL_STATE_INDEX);
|
||||||
|
return arc;
|
||||||
|
}
|
||||||
|
|
||||||
|
info = FState::StaticFindStateOwner (state);
|
||||||
|
|
||||||
|
if (info != NULL)
|
||||||
|
{
|
||||||
|
arc.UserWriteClass (info);
|
||||||
|
arc.WriteCount ((DWORD)(state - info->OwnedStates));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* this was never working as intended.
|
||||||
|
I_Error ("Cannot find owner for state %p:\n"
|
||||||
|
"%s %c%c %3d [%p] -> %p", state,
|
||||||
|
sprites[state->sprite].name,
|
||||||
|
state->GetFrame() + 'A',
|
||||||
|
state->GetFullbright() ? '*' : ' ',
|
||||||
|
state->GetTics(),
|
||||||
|
state->GetAction(),
|
||||||
|
state->GetNextState());
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PClassActor *info;
|
||||||
|
DWORD ofs;
|
||||||
|
|
||||||
|
arc.UserReadClass<PClassActor>(info);
|
||||||
|
ofs = arc.ReadCount ();
|
||||||
|
if (ofs == NULL_STATE_INDEX && info == RUNTIME_CLASS(AActor))
|
||||||
|
{
|
||||||
|
state = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
state = info->OwnedStates + ofs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return arc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DObject::Serialize (FArchive &arc)
|
||||||
|
{
|
||||||
|
ObjectFlags |= OF_SerialSuccess;
|
||||||
|
}
|
Loading…
Reference in a new issue