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