diff --git a/source/exhumed/src/anubis.cpp b/source/exhumed/src/anubis.cpp index 5628bd08d..f6ba79ac4 100644 --- a/source/exhumed/src/anubis.cpp +++ b/source/exhumed/src/anubis.cpp @@ -25,8 +25,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_PS_NS -enum { kMaxAnubis = 80 }; - struct Anubis { short nHealth; @@ -39,9 +37,8 @@ struct Anubis short h; }; -Anubis AnubisList[kMaxAnubis]; - -short AnubisCount = -1; +static TArray AnubisList; +static int nAnubisDrum = 0; static actionSeq AnubisSeq[] = { { 0, 0 }, @@ -61,71 +58,84 @@ static actionSeq AnubisSeq[] = { { 43, 1 }, }; -short nAnubisDrum = 0; - -static SavegameHelper sghanubis("anubis", - SA(AnubisList), - SV(AnubisCount), - SV(nAnubisDrum), - nullptr); +FSerializer& Serialize(FSerializer& arc, const char* keyname, Anubis& w, Anubis* def) +{ + if (arc.BeginObject(keyname)) + { + arc("health", w.nHealth) + ("frame", w.nFrame) + ("action", w.nAction) + ("sprite", w.nSprite) + ("target", w.nTarget) + ("f", w.f) + ("g", w.g) + ("h", w.h) + .EndObject(); + } + return arc; +} +void SerializeAnubis(FSerializer& arc) +{ + arc("anubis", AnubisList) + ("anubisdrum", nAnubisDrum); +} void InitAnubis() { - AnubisCount = kMaxAnubis; + AnubisList.Clear(); nAnubisDrum = 1; } int BuildAnubis(int nSprite, int x, int y, int z, int nSector, int nAngle, uint8_t bIsDrummer) { - AnubisCount--; - short nAnubis = AnubisCount; - - if (nAnubis < 0) { - return -1; - } + auto nAnubis = AnubisList.Reserve(1); + auto ap = &AnubisList[nAnubis]; + spritetype* sp; if (nSprite == -1) { nSprite = insertsprite(nSector, 101); + sp = &sprite[nSprite]; } else { changespritestat(nSprite, 101); + sp = &sprite[nSprite]; - x = sprite[nSprite].x; - y = sprite[nSprite].y; - z = sector[sprite[nSprite].sectnum].floorz; - nAngle = sprite[nSprite].ang; + 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].xoffset = 0; - sprite[nSprite].shade = -12; - sprite[nSprite].yoffset = 0; - sprite[nSprite].picnum = 1; - sprite[nSprite].pal = sector[sprite[nSprite].sectnum].ceilingpal; - sprite[nSprite].clipdist = 60; - sprite[nSprite].ang = nAngle; - sprite[nSprite].xrepeat = 40; - sprite[nSprite].yrepeat = 40; - sprite[nSprite].xvel = 0; - sprite[nSprite].yvel = 0; - sprite[nSprite].zvel = 0; - 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->xoffset = 0; + sp->shade = -12; + sp->yoffset = 0; + sp->picnum = 1; + sp->pal = sector[sp->sectnum].ceilingpal; + sp->clipdist = 60; + sp->ang = nAngle; + sp->xrepeat = 40; + sp->yrepeat = 40; + sp->xvel = 0; + sp->yvel = 0; + sp->zvel = 0; + sp->hitag = 0; + sp->lotag = runlist_HeadRun() + 1; + sp->extra = -1; // GrabTimeSlot(3); if (bIsDrummer) { - AnubisList[nAnubis].nAction = nAnubisDrum + 6; + ap->nAction = nAnubisDrum + 6; nAnubisDrum++; if (nAnubisDrum >= 5) { @@ -134,16 +144,16 @@ int BuildAnubis(int nSprite, int x, int y, int z, int nSector, int nAngle, uint8 } else { - AnubisList[nAnubis].nAction = 0; + ap->nAction = 0; } - AnubisList[nAnubis].nHealth = 540; - AnubisList[nAnubis].nFrame = 0; - AnubisList[nAnubis].nSprite = nSprite; - AnubisList[nAnubis].nTarget = -1; - AnubisList[nAnubis].g = 0; + ap->nHealth = 540; + ap->nFrame = 0; + ap->nSprite = nSprite; + ap->nTarget = -1; + ap->g = 0; - sprite[nSprite].owner = runlist_AddRunRec(sprite[nSprite].lotag - 1, nAnubis | 0x90000); + sp->owner = runlist_AddRunRec(sp->lotag - 1, nAnubis | 0x90000); runlist_AddRunRec(NewRun, nAnubis | 0x90000); nCreaturesTotal++; @@ -154,10 +164,12 @@ 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; - assert(nAnubis >= 0 && nAnubis < kMaxAnubis); + auto ap = &AnubisList[nAnubis]; + assert(nAnubis >= 0 && nAnubis < (int)AnubisList.Size()); - short nSprite = AnubisList[nAnubis].nSprite; - short nAction = AnubisList[nAnubis].nAction; + short nSprite = ap->nSprite; + auto sp = &sprite[nSprite]; + short nAction = ap->nAction; bool bVal = false; @@ -179,20 +191,20 @@ void FuncAnubis(int a, int nDamage, int nRun) short nSeq = SeqOffsets[kSeqAnubis] + AnubisSeq[nAction].a; - seq_MoveSequence(nSprite, nSeq, AnubisList[nAnubis].nFrame); + seq_MoveSequence(nSprite, nSeq, ap->nFrame); - sprite[nSprite].picnum = seq_GetSeqPicnum2(nSeq, AnubisList[nAnubis].nFrame); + sp->picnum = seq_GetSeqPicnum2(nSeq, ap->nFrame); - AnubisList[nAnubis].nFrame++; - if (AnubisList[nAnubis].nFrame >= SeqSize[nSeq]) + ap->nFrame++; + if (ap->nFrame >= SeqSize[nSeq]) { - AnubisList[nAnubis].nFrame = 0; + ap->nFrame = 0; bVal = true; } - short nTarget = AnubisList[nAnubis].nTarget; + short nTarget = ap->nTarget; - short nFrame = SeqBase[nSeq] + AnubisList[nAnubis].nFrame; + short nFrame = SeqBase[nSeq] + ap->nFrame; short nFlag = FrameFlag[nFrame]; int nMov = 0; @@ -214,12 +226,12 @@ void FuncAnubis(int a, int nDamage, int nRun) if (nTarget >= 0) { D3PlayFX(StaticSound[kSound8], nSprite); - AnubisList[nAnubis].nAction = 1; - AnubisList[nAnubis].nFrame = 0; - AnubisList[nAnubis].nTarget = nTarget; + ap->nAction = 1; + ap->nFrame = 0; + ap->nTarget = nTarget; - sprite[nSprite].xvel = bcos(sprite[nSprite].ang, -2); - sprite[nSprite].yvel = bsin(sprite[nSprite].ang, -2); + sp->xvel = bcos(sp->ang, -2); + sp->yvel = bsin(sp->ang, -2); } } return; @@ -230,9 +242,9 @@ void FuncAnubis(int a, int nDamage, int nRun) { PlotCourseToSprite(nSprite, nTarget); - int nAngle = sprite[nSprite].ang & 0xFFF8; - sprite[nSprite].xvel = bcos(nAngle, -2); - sprite[nSprite].yvel = bsin(nAngle, -2); + int nAngle = sp->ang & 0xFFF8; + sp->xvel = bcos(nAngle, -2); + sp->yvel = bsin(nAngle, -2); } switch (nMov & 0xC000) @@ -241,13 +253,13 @@ void FuncAnubis(int a, int nDamage, int nRun) { if ((nMov & 0x3FFF) == nTarget) { - int nAng = getangle(sprite[nTarget].x - sprite[nSprite].x, sprite[nTarget].y - sprite[nSprite].y); - int nAngDiff = AngleDiff(sprite[nSprite].ang, nAng); + int nAng = getangle(sprite[nTarget].x - sp->x, sprite[nTarget].y - sp->y); + int nAngDiff = AngleDiff(sp->ang, nAng); if (nAngDiff < 64) { - AnubisList[nAnubis].nAction = 2; - AnubisList[nAnubis].nFrame = 0; + ap->nAction = 2; + ap->nFrame = 0; } break; } @@ -256,33 +268,33 @@ void FuncAnubis(int a, int nDamage, int nRun) } case 0x8000: { - sprite[nSprite].ang = (sprite[nSprite].ang + 256) & kAngleMask; - sprite[nSprite].xvel = bcos(sprite[nSprite].ang, -2); - sprite[nSprite].yvel = bsin(sprite[nSprite].ang, -2); + sp->ang = (sp->ang + 256) & kAngleMask; + sp->xvel = bcos(sp->ang, -2); + sp->yvel = bsin(sp->ang, -2); break; } default: { - if (AnubisList[nAnubis].g) + if (ap->g) { - AnubisList[nAnubis].g--; + ap->g--; } else { - AnubisList[nAnubis].g = 60; + ap->g = 60; if (nTarget > -1) // NOTE: nTarget can be -1. this check wasn't in original code. TODO: demo compatiblity? { - if (cansee(sprite[nSprite].x, sprite[nSprite].y, sprite[nSprite].z - GetSpriteHeight(nSprite), sprite[nSprite].sectnum, + if (cansee(sp->x, sp->y, sp->z - GetSpriteHeight(nSprite), sp->sectnum, sprite[nTarget].x, sprite[nTarget].y, sprite[nTarget].z - GetSpriteHeight(nTarget), sprite[nTarget].sectnum)) { - sprite[nSprite].xvel = 0; - sprite[nSprite].yvel = 0; - sprite[nSprite].ang = GetMyAngle(sprite[nTarget].x - sprite[nSprite].x, sprite[nTarget].y - sprite[nSprite].y); + sp->xvel = 0; + sp->yvel = 0; + sp->ang = GetMyAngle(sprite[nTarget].x - sp->x, sprite[nTarget].y - sp->y); - AnubisList[nAnubis].nAction = 3; - AnubisList[nAnubis].nFrame = 0; + ap->nAction = 3; + ap->nFrame = 0; } } } @@ -295,14 +307,14 @@ void FuncAnubis(int a, int nDamage, int nRun) { if (nTarget == -1) { - AnubisList[nAnubis].nAction = 0; - AnubisList[nAnubis].g = 50; + ap->nAction = 0; + ap->g = 50; } else { if (PlotCourseToSprite(nSprite, nTarget) >= 768) { - AnubisList[nAnubis].nAction = 1; + ap->nAction = 1; } else { @@ -319,18 +331,18 @@ void FuncAnubis(int a, int nDamage, int nRun) { if (bVal) { - AnubisList[nAnubis].nAction = 1; + ap->nAction = 1; - sprite[nSprite].xvel = bcos(sprite[nSprite].ang, -2); - sprite[nSprite].yvel = bsin(sprite[nSprite].ang, -2); - AnubisList[nAnubis].nFrame = 0; + sp->xvel = bcos(sp->ang, -2); + sp->yvel = bsin(sp->ang, -2); + ap->nFrame = 0; } else { // loc_25718: if (nFlag & 0x80) { - BuildBullet(nSprite, 8, 0, 0, -1, sprite[nSprite].ang, nTarget + 10000, 1); + BuildBullet(nSprite, 8, 0, 0, -1, sp->ang, nTarget + 10000, 1); } } @@ -339,13 +351,13 @@ void FuncAnubis(int a, int nDamage, int nRun) case 4: case 5: { - sprite[nSprite].xvel = 0; - sprite[nSprite].yvel = 0; + sp->xvel = 0; + sp->yvel = 0; if (bVal) { - AnubisList[nAnubis].nAction = 1; - AnubisList[nAnubis].nFrame = 0; + ap->nAction = 1; + ap->nFrame = 0; } return; } @@ -357,8 +369,8 @@ void FuncAnubis(int a, int nDamage, int nRun) { if (bVal) { - AnubisList[nAnubis].nAction = (RandomSize(3) % 5) + 6; - AnubisList[nAnubis].nFrame = 0; + ap->nAction = (RandomSize(3) % 5) + 6; + ap->nFrame = 0; } return; } @@ -367,18 +379,18 @@ void FuncAnubis(int a, int nDamage, int nRun) { if (bVal) { - AnubisList[nAnubis].nAction = nAction + 2; - AnubisList[nAnubis].nFrame = 0; + ap->nAction = nAction + 2; + ap->nFrame = 0; - sprite[nSprite].xvel = 0; - sprite[nSprite].yvel = 0; + sp->xvel = 0; + sp->yvel = 0; } return; } case 13: case 14: { - sprite[nSprite].cstat &= 0xFEFE; + sp->cstat &= 0xFEFE; return; } @@ -391,13 +403,13 @@ void FuncAnubis(int a, int nDamage, int nRun) { if (!(sprite[nTarget].cstat & 0x101)) { - AnubisList[nAnubis].nAction = 0; - AnubisList[nAnubis].nFrame = 0; - AnubisList[nAnubis].g = 100; - AnubisList[nAnubis].nTarget = -1; + ap->nAction = 0; + ap->nFrame = 0; + ap->g = 100; + ap->nTarget = -1; - sprite[nSprite].xvel = 0; - sprite[nSprite].yvel = 0; + sp->xvel = 0; + sp->yvel = 0; } } @@ -406,7 +418,7 @@ void FuncAnubis(int a, int nDamage, int nRun) case 0x90000: { - seq_PlotSequence(a & 0xFFFF, SeqOffsets[kSeqAnubis] + AnubisSeq[nAction].a, AnubisList[nAnubis].nFrame, AnubisSeq[nAction].b); + seq_PlotSequence(a & 0xFFFF, SeqOffsets[kSeqAnubis] + AnubisSeq[nAction].a, ap->nFrame, AnubisSeq[nAction].b); break; } @@ -423,12 +435,12 @@ void FuncAnubis(int a, int nDamage, int nRun) { if (nDamage) { - if (AnubisList[nAnubis].nHealth <= 0) + if (ap->nHealth <= 0) return; - AnubisList[nAnubis].nHealth -= nDamage; + ap->nHealth -= nDamage; - if (AnubisList[nAnubis].nHealth > 0) + if (ap->nHealth > 0) { short nTarget = a & 0xFFFF; @@ -440,7 +452,7 @@ void FuncAnubis(int a, int nDamage, int nRun) if (sprite[nTarget].statnum == 100 || sprite[nTarget].statnum < 199) { if (!RandomSize(5)) { - AnubisList[nAnubis].nTarget = nTarget; + ap->nTarget = nTarget; } } @@ -448,10 +460,10 @@ void FuncAnubis(int a, int nDamage, int nRun) { if (nAction >= 6 && nAction <= 10) { - int nDrumSprite = insertsprite(sprite[nSprite].sectnum, kStatAnubisDrum); + int nDrumSprite = insertsprite(sp->sectnum, kStatAnubisDrum); - sprite[nDrumSprite].x = sprite[nSprite].x; - sprite[nDrumSprite].y = sprite[nSprite].y; + sprite[nDrumSprite].x = sp->x; + sprite[nDrumSprite].y = sp->y; sprite[nDrumSprite].z = sector[sprite[nDrumSprite].sectnum].floorz; sprite[nDrumSprite].xrepeat = 40; sprite[nDrumSprite].yrepeat = 40; @@ -460,8 +472,8 @@ void FuncAnubis(int a, int nDamage, int nRun) BuildObject(nDrumSprite, 2, 0); } - AnubisList[nAnubis].nAction = 4; - AnubisList[nAnubis].nFrame = 0; + ap->nAction = 4; + ap->nFrame = 0; } else { @@ -472,21 +484,21 @@ void FuncAnubis(int a, int nDamage, int nRun) else { // he ded. - sprite[nSprite].xvel = 0; - sprite[nSprite].yvel = 0; - sprite[nSprite].zvel = 0; - sprite[nSprite].z = sector[sprite[nSprite].sectnum].floorz; - sprite[nSprite].cstat &= 0xFEFE; + sp->xvel = 0; + sp->yvel = 0; + sp->zvel = 0; + sp->z = sector[sp->sectnum].floorz; + sp->cstat &= 0xFEFE; - AnubisList[nAnubis].nHealth = 0; + ap->nHealth = 0; nCreaturesKilled++; if (nAction < 11) { DropMagic(nSprite); - AnubisList[nAnubis].nAction = (nMessage == 0xA0000) + 11; - AnubisList[nAnubis].nFrame = 0; + ap->nAction = (nMessage == 0xA0000) + 11; + ap->nFrame = 0; } } } diff --git a/source/exhumed/src/exhumed.h b/source/exhumed/src/exhumed.h index 37647dd12..1a3bfec46 100644 --- a/source/exhumed/src/exhumed.h +++ b/source/exhumed/src/exhumed.h @@ -247,6 +247,7 @@ struct GameInterface : ::GameInterface void MenuSound(EMenuSounds snd) override; bool StartGame(FNewGameStartup& gs) override; FSavegameInfo GetSaveSig() override; + void SerializeGameState(FSerializer& arc); bool LoadGame() override; bool SaveGame() override; bool CanSave() override; diff --git a/source/exhumed/src/save.cpp b/source/exhumed/src/save.cpp index 1f530302b..d00edfe21 100644 --- a/source/exhumed/src/save.cpp +++ b/source/exhumed/src/save.cpp @@ -29,6 +29,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_PS_NS +void SerializeAnubis(FSerializer& arc); + + void SaveTextureState(); void LoadTextureState(); @@ -41,6 +44,12 @@ bool GameInterface::SaveGame() return 1; // CHECKME } +void GameInterface::SerializeGameState(FSerializer& arc) +{ + SerializeAnubis(arc); +} + + bool GameInterface::LoadGame() {