mirror of
https://github.com/ZDoom/Raze.git
synced 2025-02-18 01:31:11 +00:00
implemented a serializer for DCustomDude
This writes out the entire object. It is not economical to cut this down and rewrite the init code to make this less heavy.
This commit is contained in:
parent
30826ef22f
commit
b8aee5a730
4 changed files with 466 additions and 11 deletions
|
@ -687,6 +687,7 @@ set( NOT_COMPILED_SOURCE_FILES
|
|||
games/blood/src/nnextstr.cpp
|
||||
games/blood/src/nnextsif.cpp
|
||||
games/blood/src/nnextcdud.cpp
|
||||
games/blood/src/nnextcdudserialize.cpp
|
||||
|
||||
games/blood/src/osdcmd.cpp
|
||||
games/blood/src/player.cpp
|
||||
|
|
|
@ -75,6 +75,7 @@
|
|||
#include "src/nnextsif.cpp"
|
||||
#include "src/nnextstr.cpp"
|
||||
#include "src/nnextcdud.cpp"
|
||||
#include "src/nnextcdudserialize.cpp"
|
||||
#endif
|
||||
|
||||
// after nnsprinsect
|
||||
|
|
|
@ -681,7 +681,7 @@ class CUSTOMDUDE_WEAPON
|
|||
shot;
|
||||
struct AMMO
|
||||
{
|
||||
unsigned int cur, total : 16;
|
||||
uint16_t cur, total;
|
||||
void SetTotal(int nVal) { total = nVal; }
|
||||
void SetFull() { Set(total); }
|
||||
void Set(int nVal) { cur = ClipRange(nVal, 0, total); }
|
||||
|
@ -837,6 +837,10 @@ class CUSTOMDUDE_GIB
|
|||
class CUSTOMDUDE_EFFECT
|
||||
{
|
||||
public:
|
||||
TArray<int> pAnims; // SEQ IDs
|
||||
TArray<int> pFrames; // SEQ frame indices
|
||||
TArray<int> pStates; // type to be determined
|
||||
|
||||
unsigned short id[kCdudeMaxEffects];
|
||||
unsigned int clock;
|
||||
signed int liveTime;
|
||||
|
@ -851,21 +855,19 @@ class CUSTOMDUDE_EFFECT
|
|||
unsigned short delay[2];
|
||||
CUSTOMDUDE_GIB spr2gib;
|
||||
APPEARANCE appearance;
|
||||
TArray<int> pAnims; // SEQ IDs
|
||||
TArray<int> pFrames; // SEQ frame indices
|
||||
TArray<int> pStates; // type to be determined
|
||||
DVector3 offset;
|
||||
void Clear()
|
||||
{
|
||||
memset(this, 0, sizeof(CUSTOMDUDE_EFFECT));
|
||||
pAnims.Clear();
|
||||
pFrames.Clear();
|
||||
pStates.Clear();
|
||||
// do not memset the TArrays!
|
||||
memset(id, 0, sizeof(CUSTOMDUDE_EFFECT) - myoffsetof(CUSTOMDUDE_EFFECT, id));
|
||||
angle = DAngle360;
|
||||
_velocity = -1;
|
||||
chance = 0x10000;
|
||||
srcVelocity = 1;
|
||||
|
||||
pAnims.Clear();
|
||||
pFrames.Clear();
|
||||
pStates.Clear();
|
||||
}
|
||||
|
||||
bool CanSpawn(DBloodActor* pSpr)
|
||||
|
@ -1020,7 +1022,7 @@ class CUSTOMDUDE_DAMAGE
|
|||
{
|
||||
public:
|
||||
unsigned short id[kDmgMax];
|
||||
unsigned int ignoreSources : 8;
|
||||
uint8_t ignoreSources;
|
||||
void Set(int nVal, int nFor) { id[nFor] = ClipRange(nVal, 0, kCdudeMaxDmgScale); }
|
||||
void Inc(int nVal, int nFor) { Set(id[nFor] + abs(nVal), nFor); }
|
||||
void Dec(int nVal, int nFor) { Set(id[nFor] - abs(nVal), nFor); }
|
||||
|
@ -1029,7 +1031,7 @@ class CUSTOMDUDE_DAMAGE
|
|||
class CUSTOMDUDE_DODGE
|
||||
{
|
||||
public:
|
||||
struct
|
||||
struct DAMAGE
|
||||
{
|
||||
unsigned int times;
|
||||
unsigned int timer;
|
||||
|
@ -1058,7 +1060,7 @@ class CUSTOMDUDE_DODGE
|
|||
}
|
||||
}
|
||||
onDamage;
|
||||
struct
|
||||
struct AIMMISS
|
||||
{
|
||||
unsigned int chance;
|
||||
bool Allow(void) { return Chance(chance); }
|
||||
|
@ -1195,6 +1197,7 @@ class DCustomDude : public DObject
|
|||
|
||||
size_t PropagateMark() override;
|
||||
void OnDestroy();
|
||||
void Serialize(FSerializer& arc) override;
|
||||
|
||||
// Note: we will likely have to write out the entire shit here to make this savegame robust...
|
||||
public:
|
||||
|
|
450
source/games/blood/src/nnextcdudserialize.cpp
Normal file
450
source/games/blood/src/nnextcdudserialize.cpp
Normal file
|
@ -0,0 +1,450 @@
|
|||
/*
|
||||
* Copyright (C) 2023 Christoph Oelckers
|
||||
*
|
||||
* This file is part of Raze
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifdef NOONE_EXTENSIONS
|
||||
#pragma once
|
||||
#include "nnextcdud.h"
|
||||
|
||||
BEGIN_BLD_NS
|
||||
|
||||
// this code writes out the entire custom dude because there is really no good way to partially run the setup code on savegame reload
|
||||
|
||||
FSerializer& Serialize(FSerializer& arc, const char* keyname, CUSTOMDUDE_SOUND& w, CUSTOMDUDE_SOUND* def)
|
||||
{
|
||||
if (arc.BeginObject(keyname))
|
||||
{
|
||||
arc.Array("id", w.id, kCdudeMaxSounds)
|
||||
("medium", w.medium)
|
||||
("ai", w.ai)
|
||||
("interruptable", w.interruptable)
|
||||
("once", w.once)
|
||||
("volume", w.volume)
|
||||
.EndObject();
|
||||
}
|
||||
return arc;
|
||||
}
|
||||
|
||||
FSerializer& Serialize(FSerializer& arc, const char* keyname, APPEARANCE& w, APPEARANCE* def)
|
||||
{
|
||||
if (arc.BeginObject(keyname))
|
||||
{
|
||||
arc("sound", w.sound)
|
||||
.Array("scl", w.scl, 2)
|
||||
("available", w.available)
|
||||
("soundAvailable", w.soundAvailable)
|
||||
("seq", w.seq)
|
||||
("pic", w.pic)
|
||||
("clb", w.clb)
|
||||
("xrp", w.xrp)
|
||||
("yrp", w.yrp)
|
||||
("xof", w.xof)
|
||||
("yof", w.yof)
|
||||
("pal", w.pal)
|
||||
("shd", w.shd)
|
||||
.EndObject();
|
||||
}
|
||||
return arc;
|
||||
}
|
||||
|
||||
FSerializer& Serialize(FSerializer& arc, const char* keyname, CUSTOMDUDE_WEAPON::SHOT& w, CUSTOMDUDE_WEAPON::SHOT* def)
|
||||
{
|
||||
if (arc.BeginObject(keyname))
|
||||
{
|
||||
arc
|
||||
("velocity", w._velocity)
|
||||
("slope", w.slope)
|
||||
("targetfollow", w.targetFollow)
|
||||
("clipdist", w.clipdist)
|
||||
("impact", w.impact)
|
||||
("remtime", w.remTime)
|
||||
("appearance", w.appearance)
|
||||
("offset", w.offset)
|
||||
.EndObject();
|
||||
}
|
||||
return arc;
|
||||
}
|
||||
|
||||
FSerializer& Serialize(FSerializer& arc, const char* keyname, CUSTOMDUDE_WEAPON::AMMO& w, CUSTOMDUDE_WEAPON::AMMO* def)
|
||||
{
|
||||
if (arc.BeginObject(keyname))
|
||||
{
|
||||
arc
|
||||
("cur", w.cur)
|
||||
("total", w.total)
|
||||
.EndObject();
|
||||
}
|
||||
return arc;
|
||||
}
|
||||
|
||||
FSerializer& Serialize(FSerializer& arc, const char* keyname, CUSTOMDUDE_WEAPON::COOLDOWN& w, CUSTOMDUDE_WEAPON::COOLDOWN* def)
|
||||
{
|
||||
if (arc.BeginObject(keyname))
|
||||
{
|
||||
arc
|
||||
("clock", w.clock)
|
||||
("delay", w.delay)
|
||||
("usecount", w.useCount)
|
||||
("total", w.totalUseCount)
|
||||
.EndObject();
|
||||
}
|
||||
return arc;
|
||||
}
|
||||
|
||||
FSerializer& Serialize(FSerializer& arc, const char* keyname, CUSTOMDUDE_WEAPON::SHOT_STYLE& w, CUSTOMDUDE_WEAPON::SHOT_STYLE* def)
|
||||
{
|
||||
if (arc.BeginObject(keyname))
|
||||
{
|
||||
arc
|
||||
("available", w.available)
|
||||
("angle", w.angle)
|
||||
("offset", w.offset)
|
||||
.EndObject();
|
||||
}
|
||||
return arc;
|
||||
}
|
||||
|
||||
FSerializer& Serialize(FSerializer& arc, const char* keyname, CUSTOMDUDE_WEAPON& w, CUSTOMDUDE_WEAPON* def)
|
||||
{
|
||||
if (arc.BeginObject(keyname))
|
||||
{
|
||||
arc
|
||||
("type", w.type)
|
||||
("numshots", w.numshots)
|
||||
("id", w.id)
|
||||
("sharedid", w.sharedId)
|
||||
("angle", w.angle)
|
||||
("medium", w.medium)
|
||||
("pickchance", w.pickChance)
|
||||
("available", w.available)
|
||||
("posture", w.posture)
|
||||
("interruptable", w.interruptable)
|
||||
("turntotarget", w.turnToTarget)
|
||||
("stateid", w.stateID)
|
||||
("nextstateid", w.nextStateID)
|
||||
("clipmask", w.clipMask)
|
||||
("group", w.group)
|
||||
.Array("dispersion", w.dispersion, 2)
|
||||
.Array("distrange", w.distRange, 2)
|
||||
.Array("targethprange", w.targHpRange, 2)
|
||||
.Array("dudehprange", w.dudeHpRange, 2)
|
||||
("sound", w.sound)
|
||||
.EndObject();
|
||||
}
|
||||
return arc;
|
||||
}
|
||||
|
||||
FSerializer& Serialize(FSerializer& arc, const char* keyname, CUSTOMDUDE_GIB& w, CUSTOMDUDE_GIB* def)
|
||||
{
|
||||
if (arc.BeginObject(keyname))
|
||||
{
|
||||
arc
|
||||
("available", w.available)
|
||||
("force", w.force)
|
||||
("trflags", w.trFlags)
|
||||
("physics", w.physics)
|
||||
("thingtype", w.thingType)
|
||||
("data1", w.data1)
|
||||
("data2", w.data2)
|
||||
("data3", w.data3)
|
||||
("data4", w.data4)
|
||||
.EndObject();
|
||||
}
|
||||
return arc;
|
||||
}
|
||||
|
||||
FSerializer& Serialize(FSerializer& arc, const char* keyname, CUSTOMDUDE_EFFECT& w, CUSTOMDUDE_EFFECT* def)
|
||||
{
|
||||
if (arc.BeginObject(keyname))
|
||||
{
|
||||
arc
|
||||
.Array("id", w.id, kCdudeMaxEffects)
|
||||
("clock", w.clock)
|
||||
("livetime", w.liveTime)
|
||||
("velocity", w._velocity)
|
||||
("velocityslope", w._velocitySlope)
|
||||
("angle", w.angle)
|
||||
("posture", w.posture)
|
||||
("medium", w.medium)
|
||||
("allunique", w.allUnique)
|
||||
("srcVelocity", w.srcVelocity)
|
||||
("chance", w.chance)
|
||||
.Array("delay", w.delay, 2)
|
||||
("spr2gib", w.spr2gib)
|
||||
("appearance", w.appearance)
|
||||
("anims", w.pAnims)
|
||||
("frames", w.pFrames)
|
||||
("states", w.pStates)
|
||||
("offset", w.offset)
|
||||
.EndObject();
|
||||
}
|
||||
return arc;
|
||||
}
|
||||
|
||||
FSerializer& Serialize(FSerializer& arc, const char* keyname, CUSTOMDUDE_DAMAGE& w, CUSTOMDUDE_DAMAGE* def)
|
||||
{
|
||||
if (arc.BeginObject(keyname))
|
||||
{
|
||||
arc
|
||||
.Array("id", w.id, kDmgMax)
|
||||
("ignoreSources", w.ignoreSources)
|
||||
.EndObject();
|
||||
}
|
||||
return arc;
|
||||
}
|
||||
|
||||
FSerializer& Serialize(FSerializer& arc, const char* keyname, CUSTOMDUDE_DODGE::DAMAGE& w, CUSTOMDUDE_DODGE::DAMAGE* def)
|
||||
{
|
||||
if (arc.BeginObject(keyname))
|
||||
{
|
||||
arc
|
||||
("times", w.times)
|
||||
("timer", w.timer)
|
||||
("chance", w.chance)
|
||||
("dmgReq", w.dmgReq)
|
||||
.EndObject();
|
||||
}
|
||||
return arc;
|
||||
}
|
||||
|
||||
FSerializer& Serialize(FSerializer& arc, const char* keyname, CUSTOMDUDE_DODGE::AIMMISS& w, CUSTOMDUDE_DODGE::AIMMISS* def)
|
||||
{
|
||||
if (arc.BeginObject(keyname))
|
||||
{
|
||||
arc
|
||||
("chance", w.chance)
|
||||
.EndObject();
|
||||
}
|
||||
return arc;
|
||||
}
|
||||
|
||||
FSerializer& Serialize(FSerializer& arc, const char* keyname, CUSTOMDUDE_DODGE& w, CUSTOMDUDE_DODGE* def)
|
||||
{
|
||||
if (arc.BeginObject(keyname))
|
||||
{
|
||||
arc
|
||||
("ondamage", w.onDamage)
|
||||
("onaimmiss", w.onAimMiss)
|
||||
.EndObject();
|
||||
}
|
||||
return arc;
|
||||
}
|
||||
|
||||
FSerializer& Serialize(FSerializer& arc, const char* keyname, CUSTOMDUDE_RECOIL& w, CUSTOMDUDE_RECOIL* def)
|
||||
{
|
||||
if (arc.BeginObject(keyname))
|
||||
{
|
||||
arc
|
||||
("times", w.times)
|
||||
("timer", w.timer)
|
||||
("chance", w.chance)
|
||||
("dmgReq", w.dmgReq)
|
||||
.EndObject();
|
||||
}
|
||||
return arc;
|
||||
}
|
||||
|
||||
FSerializer& Serialize(FSerializer& arc, const char* keyname, CUSTOMDUDE_KNOCKOUT& w, CUSTOMDUDE_KNOCKOUT* def)
|
||||
{
|
||||
if (arc.BeginObject(keyname))
|
||||
{
|
||||
arc
|
||||
("times", w.times)
|
||||
("timer", w.timer)
|
||||
("chance", w.chance)
|
||||
("dmgReq", w.dmgReq)
|
||||
.EndObject();
|
||||
}
|
||||
return arc;
|
||||
}
|
||||
|
||||
FSerializer& Serialize(FSerializer& arc, const char* keyname, CUSTOMDUDE_VELOCITY& w, CUSTOMDUDE_VELOCITY* def)
|
||||
{
|
||||
if (arc.BeginObject(keyname))
|
||||
{
|
||||
arc
|
||||
.Array("id", w.id, kParVelocityMax)
|
||||
.EndObject();
|
||||
}
|
||||
return arc;
|
||||
}
|
||||
|
||||
FSerializer& Serialize(FSerializer& arc, const char* keyname, CUSTOMDUDE_DROPITEM::itemdesc& w, CUSTOMDUDE_DROPITEM::itemdesc* def)
|
||||
{
|
||||
if (arc.BeginObject(keyname))
|
||||
{
|
||||
arc
|
||||
("class", w.cls)
|
||||
("percent", w.perc)
|
||||
.EndObject();
|
||||
}
|
||||
return arc;
|
||||
}
|
||||
|
||||
FSerializer& Serialize(FSerializer& arc, const char* keyname, CUSTOMDUDE_DROPITEM& w, CUSTOMDUDE_DROPITEM* def)
|
||||
{
|
||||
if (arc.BeginObject(keyname))
|
||||
{
|
||||
arc
|
||||
.Array("items", w.items, kCdudeMaxDropItems)
|
||||
("sprDropItemChance", w.sprDropItemChance)
|
||||
.EndObject();
|
||||
}
|
||||
return arc;
|
||||
}
|
||||
|
||||
END_BLD_NS
|
||||
|
||||
// this one's ugly because there is no easy way to retrieve the function records, especially later for scripted functions.
|
||||
// We have to cheat.
|
||||
// To avoid endless leaking allocations we store what we create for reuse later.
|
||||
// Note that we cannot reference the holding array because it can reallocate.
|
||||
// Once stats can be defined via scripts this will become unnecessary.
|
||||
static TArray<VMNativeFunction**> vmfuncpointers;
|
||||
template<>
|
||||
FSerializer& Serialize(FSerializer& arc, const char* key, VMNativeFunction**& pfunc, VMNativeFunction***)
|
||||
{
|
||||
VMFunction* func = pfunc ? *pfunc : nullptr;
|
||||
arc(key, func);
|
||||
if (arc.isReading())
|
||||
{
|
||||
if (func == nullptr) pfunc = nullptr;
|
||||
else
|
||||
{
|
||||
auto pos = vmfuncpointers.FindEx([&](const auto& element) { return *element == func; });
|
||||
if (pos < vmfuncpointers.Size()) pfunc = vmfuncpointers[pos];
|
||||
else
|
||||
{
|
||||
// put these in a place where automatic maintenance will get rid of them later.
|
||||
VMNativeFunction** fakep = (VMNativeFunction**)ClassDataAllocator.Alloc(sizeof(VMFunction*));
|
||||
vmfuncpointers.Push(fakep);
|
||||
pfunc = fakep;
|
||||
}
|
||||
}
|
||||
}
|
||||
return arc;
|
||||
}
|
||||
|
||||
BEGIN_BLD_NS
|
||||
|
||||
FSerializer& Serialize(FSerializer& arc, const char* keyname, AISTATE& w, AISTATE* def)
|
||||
{
|
||||
if (arc.BeginObject(keyname))
|
||||
{
|
||||
arc
|
||||
("stateType", w.stateType)
|
||||
("seqId", w.seqId)
|
||||
("enterFunc", w.enterFunc)
|
||||
("moveFunc", w.moveFunc)
|
||||
("thinkFunc", w.thinkFunc)
|
||||
("funcId", w.funcId)
|
||||
("stateTicks", w.stateTicks)
|
||||
("nextState", w.nextState)
|
||||
.EndObject();
|
||||
}
|
||||
return arc;
|
||||
}
|
||||
|
||||
FSerializer& Serialize(FSerializer& arc, const char* keyname, NextDudeInfo& w, NextDudeInfo* def)
|
||||
{
|
||||
if (arc.BeginObject(keyname))
|
||||
{
|
||||
size_t index = w.index();
|
||||
arc("index", index);
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
auto v = *std::get_if<bool>(&w);
|
||||
arc("v", v);
|
||||
w = v;
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
auto v = *std::get_if<int>(&w);
|
||||
arc("v", v);
|
||||
w = v;
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
auto v = *std::get_if<PClass*>(&w);
|
||||
arc("v", v);
|
||||
w = v;
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
auto v = *std::get_if<DBloodActor*>(&w);
|
||||
arc("v", v);
|
||||
w = v;
|
||||
break;
|
||||
}
|
||||
}
|
||||
arc.EndObject();
|
||||
}
|
||||
return arc;
|
||||
}
|
||||
|
||||
void DCustomDude::Serialize(FSerializer & arc)
|
||||
{
|
||||
Super::Serialize(arc);
|
||||
|
||||
arc
|
||||
("version", version)
|
||||
("initialized", initialized)
|
||||
("numEffects", numEffects)
|
||||
("numWeapons", numWeapons)
|
||||
("pSpr", pSpr)
|
||||
("pSpr", pLeech)
|
||||
.Array("weapons", weapons, kCdudeMaxWeapons)
|
||||
("damage", damage)
|
||||
.Array("velocity", velocity, kCdudePostureMax)
|
||||
.Array("sound", sound, kCdudeSndMax)
|
||||
("dodge", dodge)
|
||||
("recoil", recoil)
|
||||
("knockout", knockout)
|
||||
("dropItem", dropItem)
|
||||
.Array("effects", effects, kCdudeMaxEffectGroups)
|
||||
.Array("states", states[0], kCdudeStateMax * kCdudePostureMax)
|
||||
("pSlaves", pSlaves)
|
||||
("triggerSeqs", triggerSeqs)
|
||||
("medium", medium)
|
||||
("posture", posture)
|
||||
("mass", mass)
|
||||
("largestPic", largestPic)
|
||||
("prevSector", prevSector)
|
||||
("seeDist", _seeDist)
|
||||
("hearDist", _hearDist)
|
||||
("periphery", periphery)
|
||||
("fallHeight", fallHeight)
|
||||
("nextDude", nextDude)
|
||||
|
||||
;
|
||||
|
||||
|
||||
size_t weap = pWeapon ? pWeapon - weapons : ~0u;
|
||||
arc("curweapon", weap);
|
||||
if (arc.isReading()) pWeapon = weap == ~0u ? nullptr : weapons + weap;
|
||||
arc.EndObject();
|
||||
|
||||
if (arc.isReading()) pInfo = getDudeInfo(pSpr->GetType());
|
||||
}
|
||||
|
||||
END_BLD_NS
|
||||
#endif
|
Loading…
Reference in a new issue