- Exhumed: limit removal, cleanup and JSON serialization for the spider.

This commit is contained in:
Christoph Oelckers 2020-11-29 19:31:49 +01:00
parent b26f6157e9
commit e81dbbdc93
3 changed files with 149 additions and 132 deletions

View file

@ -163,11 +163,11 @@ int BuildAnubis(int nSprite, int x, int y, int z, int nSector, int nAngle, uint8
void FuncAnubis(int a, int nDamage, int nRun)
{
short nAnubis = RunData[nRun].nVal;
int nAnubis = RunData[nRun].nVal;
auto ap = &AnubisList[nAnubis];
assert(nAnubis >= 0 && nAnubis < (int)AnubisList.Size());
short nSprite = ap->nSprite;
int nSprite = ap->nSprite;
auto sp = &sprite[nSprite];
short nAction = ap->nAction;

View file

@ -30,6 +30,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
BEGIN_PS_NS
void SerializeAnubis(FSerializer& arc);
void SerializeSpider(FSerializer& arc);
void SaveTextureState();
@ -47,6 +48,7 @@ bool GameInterface::SaveGame()
void GameInterface::SerializeGameState(FSerializer& arc)
{
SerializeAnubis(arc);
SerializeSpider(arc);
}

View file

@ -25,10 +25,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
BEGIN_PS_NS
short SpiderCount = 0;
enum { kMaxSpiders = 100 };
struct Spider
{
short nHealth;
@ -39,7 +35,7 @@ struct Spider
short nRun;
};
Spider SpiderList[kMaxSpiders];
static TArray<Spider> SpiderList;
static actionSeq SpiderSeq[] = {
{16, 0},
@ -51,69 +47,86 @@ static actionSeq SpiderSeq[] = {
{41, 1}
};
static SavegameHelper sghspider("spider",
SV(SpiderCount),
SA(SpiderList),
nullptr);
FSerializer& Serialize(FSerializer& arc, const char* keyname, Spider& w, Spider* def)
{
if (arc.BeginObject(keyname))
{
arc("health", w.nHealth)
("frame", w.nFrame)
("action", w.nAction)
("sprite", w.nSprite)
("target", w.nTarget)
("run", w.nRun)
.EndObject();
}
return arc;
}
void SerializeSpider(FSerializer& arc)
{
arc("spider", SpiderList);
}
void InitSpider()
{
SpiderCount = 0;
SpiderList.Clear();
}
int BuildSpider(int nSprite, int x, int y, int z, short nSector, int nAngle)
{
int nSpider = SpiderCount++;
if (nSpider >= kMaxSpiders) {
return -1;
}
auto nSpider = SpiderList.Reserve(1);
auto spp = &SpiderList[nSpider];
spritetype* sp;
if (nSprite == -1)
{
nSprite = insertsprite(nSector, 99);
sp = &sprite[nSprite];
}
else
{
changespritestat(nSprite, 99);
x = sprite[nSprite].x;
y = sprite[nSprite].y;
z = sprite[nSprite].z;
nAngle = sprite[nSprite].ang;
sp = &sprite[nSprite];
x = sp->x;
y = sp->y;
z = sector[sp->sectnum].floorz;
nAngle = sp->ang;
}
assert(nSprite >= 0 && nSprite < kMaxSprites);
sprite[nSprite].x = x;
sprite[nSprite].y = y;
sprite[nSprite].z = z;
sprite[nSprite].cstat = 0x101;
sprite[nSprite].shade = -12;
sprite[nSprite].clipdist = 15;
sprite[nSprite].xvel = 0;
sprite[nSprite].yvel = 0;
sprite[nSprite].zvel = 0;
sprite[nSprite].xrepeat = 40;
sprite[nSprite].yrepeat = 40;
sprite[nSprite].pal = sector[sprite[nSprite].sectnum].ceilingpal;
sprite[nSprite].xoffset = 0;
sprite[nSprite].yoffset = 0;
sprite[nSprite].ang = nAngle;
sprite[nSprite].picnum = 1;
sprite[nSprite].hitag = 0;
sprite[nSprite].lotag = runlist_HeadRun() + 1;
sprite[nSprite].extra = -1;
sp->x = x;
sp->y = y;
sp->z = z;
sp->cstat = 0x101;
sp->shade = -12;
sp->clipdist = 15;
sp->xvel = 0;
sp->yvel = 0;
sp->zvel = 0;
sp->xrepeat = 40;
sp->yrepeat = 40;
sp->pal = sector[sp->sectnum].ceilingpal;
sp->xoffset = 0;
sp->yoffset = 0;
sp->ang = nAngle;
sp->picnum = 1;
sp->hitag = 0;
sp->lotag = runlist_HeadRun() + 1;
sp->extra = -1;
// GrabTimeSlot(3);
SpiderList[nSpider].nAction = 0;
SpiderList[nSpider].nFrame = 0;
SpiderList[nSpider].nSprite = nSprite;
SpiderList[nSpider].nTarget = -1;
SpiderList[nSpider].nHealth = 160;
spp->nAction = 0;
spp->nFrame = 0;
spp->nSprite = nSprite;
spp->nTarget = -1;
spp->nHealth = 160;
sprite[nSprite].owner = runlist_AddRunRec(sprite[nSprite].lotag - 1, nSpider | 0xC0000);
sp->owner = runlist_AddRunRec(sp->lotag - 1, nSpider | 0xC0000);
SpiderList[nSpider].nRun = runlist_AddRunRec(NewRun, nSpider | 0xC0000);
spp->nRun = runlist_AddRunRec(NewRun, nSpider | 0xC0000);
nCreaturesTotal++;
@ -122,13 +135,15 @@ int BuildSpider(int nSprite, int x, int y, int z, short nSector, int nAngle)
void FuncSpider(int a, int nDamage, int nRun)
{
short nSpider = RunData[nRun].nVal;
assert(nSpider >= 0 && nSpider < kMaxSpiders);
int nSpider = RunData[nRun].nVal;
auto spp = &SpiderList[nSpider];
assert(nSpider >= 0 && nSpider < (int)SpiderList.Size());
int nVel = 0;
short nSprite = SpiderList[nSpider].nSprite;
short nAction = SpiderList[nSpider].nAction;
int nSprite = spp->nSprite;
auto sp = &sprite[nSprite];
short nAction = spp->nAction;
int nMessage = a & kMessageMask;
@ -144,11 +159,11 @@ void FuncSpider(int a, int nDamage, int nRun)
{
nVel = 6;
if (SpiderList[nSpider].nHealth)
if (spp->nHealth)
{
if (sprite[nSprite].cstat & 8)
if (sp->cstat & 8)
{
sprite[nSprite].z = sector[sprite[nSprite].sectnum].ceilingz + GetSpriteHeight(nSprite);
sp->z = sector[sp->sectnum].ceilingz + GetSpriteHeight(nSprite);
}
else
{
@ -158,18 +173,18 @@ void FuncSpider(int a, int nDamage, int nRun)
int nSeq = SeqOffsets[kSeqSpider] + SpiderSeq[nAction].a;
sprite[nSprite].picnum = seq_GetSeqPicnum2(nSeq, SpiderList[nSpider].nFrame);
sp->picnum = seq_GetSeqPicnum2(nSeq, spp->nFrame);
seq_MoveSequence(nSprite, nSeq, SpiderList[nSpider].nFrame);
seq_MoveSequence(nSprite, nSeq, spp->nFrame);
int nFrameFlag = FrameFlag[SeqBase[nSeq] + SpiderList[nSpider].nFrame];
int nFrameFlag = FrameFlag[SeqBase[nSeq] + spp->nFrame];
SpiderList[nSpider].nFrame++;
if (SpiderList[nSpider].nFrame >= SeqSize[nSeq]) {
SpiderList[nSpider].nFrame = 0;
spp->nFrame++;
if (spp->nFrame >= SeqSize[nSeq]) {
spp->nFrame = 0;
}
short nTarget = SpiderList[nSpider].nTarget;
short nTarget = spp->nTarget;
if (nTarget <= -1 || sprite[nTarget].cstat & 0x101)
{
@ -188,12 +203,12 @@ void FuncSpider(int a, int nDamage, int nRun)
if (nTarget >= 0)
{
SpiderList[nSpider].nAction = 1;
SpiderList[nSpider].nFrame = 0;
SpiderList[nSpider].nTarget = nTarget;
spp->nAction = 1;
spp->nFrame = 0;
spp->nTarget = nTarget;
sprite[nSprite].xvel = bcos(sprite[nSprite].ang);
sprite[nSprite].yvel = bsin(sprite[nSprite].ang);
sp->xvel = bcos(sp->ang);
sp->yvel = bsin(sp->ang);
return;
}
}
@ -210,30 +225,30 @@ void FuncSpider(int a, int nDamage, int nRun)
}
case 4:
{
if (!SpiderList[nSpider].nFrame)
if (!spp->nFrame)
{
SpiderList[nSpider].nFrame = 0;
SpiderList[nSpider].nAction = 1;
spp->nFrame = 0;
spp->nAction = 1;
}
fallthrough__;
}
case 3:
{
case_3:
short nSector = sprite[nSprite].sectnum;
short nSector = sp->sectnum;
if (sprite[nSprite].cstat & 8)
if (sp->cstat & 8)
{
sprite[nSprite].zvel = 0;
sprite[nSprite].z = sector[nSector].ceilingz + (tileHeight(sprite[nSprite].picnum) << 5);
sp->zvel = 0;
sp->z = sector[nSector].ceilingz + (tileHeight(sp->picnum) << 5);
if (sector[nSector].ceilingstat & 1)
{
sprite[nSprite].cstat ^= 8;
sprite[nSprite].zvel = 1;
sp->cstat ^= 8;
sp->zvel = 1;
SpiderList[nSpider].nAction = 3;
SpiderList[nSpider].nFrame = 0;
spp->nAction = 3;
spp->nFrame = 0;
}
}
@ -243,30 +258,30 @@ void FuncSpider(int a, int nDamage, int nRun)
if (RandomSize(3))
{
sprite[nSprite].xvel = bcos(sprite[nSprite].ang);
sprite[nSprite].yvel = bsin(sprite[nSprite].ang);
sp->xvel = bcos(sp->ang);
sp->yvel = bsin(sp->ang);
}
else
{
sprite[nSprite].xvel = 0;
sprite[nSprite].yvel = 0;
sp->xvel = 0;
sp->yvel = 0;
}
if (SpiderList[nSpider].nAction == 1 && RandomBit())
if (spp->nAction == 1 && RandomBit())
{
if (sprite[nSprite].cstat & 8)
if (sp->cstat & 8)
{
sprite[nSprite].cstat ^= 8;
sprite[nSprite].zvel = 1;
sprite[nSprite].z = sector[nSector].ceilingz + GetSpriteHeight(nSprite);
sp->cstat ^= 8;
sp->zvel = 1;
sp->z = sector[nSector].ceilingz + GetSpriteHeight(nSprite);
}
else
{
sprite[nSprite].zvel = -5120;
sp->zvel = -5120;
}
SpiderList[nSpider].nAction = 3;
SpiderList[nSpider].nFrame = 0;
spp->nAction = 3;
spp->nFrame = 0;
if (!RandomSize(3)) {
D3PlayFX(StaticSound[kSound29], nSprite);
@ -277,12 +292,12 @@ void FuncSpider(int a, int nDamage, int nRun)
}
case 5:
{
if (!SpiderList[nSpider].nFrame)
if (!spp->nFrame)
{
runlist_DoSubRunRec(sprite[nSprite].owner);
runlist_FreeRun(sprite[nSprite].lotag - 1);
runlist_SubRunRec(SpiderList[nSpider].nRun);
sprite[nSprite].cstat = 0x8000;
runlist_DoSubRunRec(sp->owner);
runlist_FreeRun(sp->lotag - 1);
runlist_SubRunRec(spp->nRun);
sp->cstat = 0x8000;
mydeletesprite(nSprite);
}
return;
@ -301,46 +316,46 @@ void FuncSpider(int a, int nDamage, int nRun)
return;
}
SpiderList[nSpider].nAction = 1;
spp->nAction = 1;
}
else
{
SpiderList[nSpider].nAction = 0;
sprite[nSprite].xvel = 0;
sprite[nSprite].yvel = 0;
spp->nAction = 0;
sp->xvel = 0;
sp->yvel = 0;
}
SpiderList[nSpider].nFrame = 0;
spp->nFrame = 0;
break;
}
}
}
else
{
SpiderList[nSpider].nTarget = -1;
SpiderList[nSpider].nAction = 0;
SpiderList[nSpider].nFrame = 0;
spp->nTarget = -1;
spp->nAction = 0;
spp->nFrame = 0;
sprite[nSprite].xvel = 0;
sprite[nSprite].yvel = 0;
sp->xvel = 0;
sp->yvel = 0;
}
int nMov = movesprite(nSprite, sprite[nSprite].xvel << nVel, sprite[nSprite].yvel << nVel, sprite[nSprite].zvel, 1280, -1280, CLIPMASK0);
int nMov = movesprite(nSprite, sp->xvel << nVel, sp->yvel << nVel, sp->zvel, 1280, -1280, CLIPMASK0);
if (!nMov)
return;
if (nMov & 0x10000
&& sprite[nSprite].zvel < 0
&& sp->zvel < 0
&& (hihit & 0xC000) != 0xC000
&& !((sector[sprite[nSprite].sectnum].ceilingstat) & 1))
&& !((sector[sp->sectnum].ceilingstat) & 1))
{
sprite[nSprite].cstat |= 8;
sprite[nSprite].z = GetSpriteHeight(nSprite) + sector[sprite[nSprite].sectnum].ceilingz;
sprite[nSprite].zvel = 0;
sp->cstat |= 8;
sp->z = GetSpriteHeight(nSprite) + sector[sp->sectnum].ceilingz;
sp->zvel = 0;
SpiderList[nSpider].nAction = 1;
SpiderList[nSpider].nFrame = 0;
spp->nAction = 1;
spp->nFrame = 0;
return;
}
else
@ -349,20 +364,20 @@ void FuncSpider(int a, int nDamage, int nRun)
{
case 0x8000:
{
sprite[nSprite].ang = (sprite[nSprite].ang + 256) & 0x7EF;
sprite[nSprite].xvel = bcos(sprite[nSprite].ang);
sprite[nSprite].yvel = bsin(sprite[nSprite].ang);
sp->ang = (sp->ang + 256) & 0x7EF;
sp->xvel = bcos(sp->ang);
sp->yvel = bsin(sp->ang);
return;
}
case 0xC000:
{
if ((nMov & 0x3FFF) == nTarget)
{
int nAng = getangle(sprite[nTarget].x - sprite[nSprite].x, sprite[nTarget].y - sprite[nSprite].y);
if (AngleDiff(sprite[nSprite].ang, nAng) < 64)
int nAng = getangle(sprite[nTarget].x - sp->x, sprite[nTarget].y - sp->y);
if (AngleDiff(sp->ang, nAng) < 64)
{
SpiderList[nSpider].nAction = 2;
SpiderList[nSpider].nFrame = 0;
spp->nAction = 2;
spp->nFrame = 0;
}
}
return;
@ -371,10 +386,10 @@ void FuncSpider(int a, int nDamage, int nRun)
break;
}
if (SpiderList[nSpider].nAction == 3)
if (spp->nAction == 3)
{
SpiderList[nSpider].nAction = 1;
SpiderList[nSpider].nFrame = 0;
spp->nAction = 1;
spp->nFrame = 0;
}
return;
}
@ -384,13 +399,13 @@ void FuncSpider(int a, int nDamage, int nRun)
case 0x90000:
{
seq_PlotSequence(a & 0xFFFF, SeqOffsets[kSeqSpider] + SpiderSeq[nAction].a, SpiderList[nSpider].nFrame, SpiderSeq[nAction].b);
seq_PlotSequence(a & 0xFFFF, SeqOffsets[kSeqSpider] + SpiderSeq[nAction].a, spp->nFrame, SpiderSeq[nAction].b);
break;
}
case 0xA0000:
{
if (SpiderList[nSpider].nHealth <= 0)
if (spp->nHealth <= 0)
return;
nDamage = runlist_CheckRadialDamage(nSprite);
@ -405,8 +420,8 @@ void FuncSpider(int a, int nDamage, int nRun)
short nTarget = a & 0xFFFF;
SpiderList[nSpider].nHealth -= nDamage;
if (SpiderList[nSpider].nHealth > 0)
spp->nHealth -= nDamage;
if (spp->nHealth > 0)
{
/*
NOTE:
@ -416,20 +431,20 @@ void FuncSpider(int a, int nDamage, int nRun)
*/
if (nTarget > -1 && sprite[nTarget].statnum == 100)
{
SpiderList[nSpider].nTarget = nTarget;
spp->nTarget = nTarget;
}
SpiderList[nSpider].nAction = 4;
SpiderList[nSpider].nFrame = 0;
spp->nAction = 4;
spp->nFrame = 0;
}
else
{
// creature is dead, make some chunks
SpiderList[nSpider].nHealth = 0;
SpiderList[nSpider].nAction = 5;
SpiderList[nSpider].nFrame = 0;
spp->nHealth = 0;
spp->nAction = 5;
spp->nFrame = 0;
sprite[nSprite].cstat &= 0xFEFE;
sp->cstat &= 0xFEFE;
nCreaturesKilled++;