diff --git a/source/games/blood/src/actor.cpp b/source/games/blood/src/actor.cpp index baf016472..f1e0a41fa 100644 --- a/source/games/blood/src/actor.cpp +++ b/source/games/blood/src/actor.cpp @@ -6879,9 +6879,7 @@ bool actCheckRespawn(DBloodActor* actor) if (!(pSprite->type >= kDudeBase && pSprite->type < kDudeMax)) { pSprite->cstat &= ~257; - pSprite->x = actor->basePoint().x; - pSprite->y = actor->basePoint().y; - pSprite->z = actor->basePoint().z; + pSprite->pos = actor->basePoint; } evPostActor(actor, nRespawnTime, kCallbackRespawn); } diff --git a/source/games/blood/src/aibat.cpp b/source/games/blood/src/aibat.cpp index 14dac7606..5aa456a29 100644 --- a/source/games/blood/src/aibat.cpp +++ b/source/games/blood/src/aibat.cpp @@ -91,7 +91,7 @@ static void batThinkTarget(DBloodActor* actor) { pDudeExtraE->thinkTime = 0; pXSprite->goalAng += 256; - POINT3D* pTarget = &actor->basePoint(); + POINT3D* pTarget = &actor->basePoint; aiSetTarget(actor, pTarget->x, pTarget->y, pTarget->z); aiNewState(actor, &batTurn); return; diff --git a/source/games/blood/src/aiboneel.cpp b/source/games/blood/src/aiboneel.cpp index 5605a49e4..f13197c5a 100644 --- a/source/games/blood/src/aiboneel.cpp +++ b/source/games/blood/src/aiboneel.cpp @@ -103,7 +103,7 @@ static void eelThinkTarget(DBloodActor* actor) { pDudeExtraE->thinkTime = 0; pXSprite->goalAng += 256; - POINT3D* pTarget = &actor->basePoint(); + POINT3D* pTarget = &actor->basePoint; aiSetTarget(actor, pTarget->x, pTarget->y, pTarget->z); aiNewState(actor, &eelTurn); return; diff --git a/source/games/blood/src/aicerber.cpp b/source/games/blood/src/aicerber.cpp index f8e9e6c58..7816e5a30 100644 --- a/source/games/blood/src/aicerber.cpp +++ b/source/games/blood/src/aicerber.cpp @@ -259,7 +259,7 @@ static void cerberusThinkTarget(DBloodActor* actor) else if (pDudeExtraE->thinkTime >= 10 && pDudeExtraE->active) { pXSprite->goalAng += 256; - POINT3D* pTarget = &actor->basePoint(); + POINT3D* pTarget = &actor->basePoint; aiSetTarget(actor, pTarget->x, pTarget->y, pTarget->z); if (pSprite->type == kDudeCerberusTwoHead) aiNewState(actor, &cerberus139890); diff --git a/source/games/blood/src/aigarg.cpp b/source/games/blood/src/aigarg.cpp index e9345aadd..1abe26f57 100644 --- a/source/games/blood/src/aigarg.cpp +++ b/source/games/blood/src/aigarg.cpp @@ -221,7 +221,7 @@ static void gargThinkTarget(DBloodActor* actor) else if (pDudeExtraE->thinkTime >= 10 && pDudeExtraE->active) { pXSprite->goalAng += 256; - POINT3D* pTarget = &actor->basePoint(); + POINT3D* pTarget = &actor->basePoint; aiSetTarget(actor, pTarget->x, pTarget->y, pTarget->z); aiNewState(actor, &gargoyleTurn); return; diff --git a/source/games/blood/src/aighost.cpp b/source/games/blood/src/aighost.cpp index fbb97d5fd..64e1e2026 100644 --- a/source/games/blood/src/aighost.cpp +++ b/source/games/blood/src/aighost.cpp @@ -198,7 +198,7 @@ static void ghostThinkTarget(DBloodActor* actor) else if (pDudeExtraE->thinkTime >= 10 && pDudeExtraE->active) { pXSprite->goalAng += 256; - POINT3D* pTarget = &actor->basePoint(); + POINT3D* pTarget = &actor->basePoint; aiSetTarget(actor, pTarget->x, pTarget->y, pTarget->z); aiNewState(actor, &ghostTurn); return; diff --git a/source/games/blood/src/aitchern.cpp b/source/games/blood/src/aitchern.cpp index 23d46565a..a819f9752 100644 --- a/source/games/blood/src/aitchern.cpp +++ b/source/games/blood/src/aitchern.cpp @@ -228,7 +228,7 @@ static void sub_725A4(DBloodActor* actor) else if (pDudeExtraE->thinkTime >= 10 && pDudeExtraE->active) { pXSprite->goalAng += 256; - POINT3D* pTarget = &actor->basePoint(); + POINT3D* pTarget = &actor->basePoint; aiSetTarget(actor, pTarget->x, pTarget->y, pTarget->z); aiNewState(actor, &tcherno13AA28); return; diff --git a/source/games/blood/src/bloodactor.h b/source/games/blood/src/bloodactor.h index 0c3b12e8e..5ca1aef65 100644 --- a/source/games/blood/src/bloodactor.h +++ b/source/games/blood/src/bloodactor.h @@ -97,6 +97,7 @@ public: SPRITEMASS spriteMass; GENDUDEEXTRA genDudeExtra; DBloodActor* prevmarker; // needed by the nnext marker code. This originally hijacked targetX in XSPRITE + POINT3D basePoint; int cumulDamage; // this one's transient and does not need to be saved. bool explosionhackflag; // this originally hijacked the target field which is not safe when working with pointers. @@ -112,6 +113,7 @@ public: dudeExtra = {}; spriteMass = {}; hit = {}; + basePoint = {}; } bool hasX() { return sprite[index].extra > 0; } void addX() @@ -125,8 +127,6 @@ public: int& zvel() { return Blood::zvel[index]; } int GetIndex() { return s().time; } // For error printing only! This is only identical with the sprite index for items spawned at map start. - POINT3D& basePoint() { return Blood::baseSprite[index]; } - void SetOwner(DBloodActor* own) { s().owner = own ? own->s().index : -1; diff --git a/source/games/blood/src/callback.cpp b/source/games/blood/src/callback.cpp index 74f0b375e..f82dafd83 100644 --- a/source/games/blood/src/callback.cpp +++ b/source/games/blood/src/callback.cpp @@ -253,9 +253,7 @@ void Respawn(DBloodActor* actor, int) // 9 if (actor->IsDudeActor()) { int nType = pSprite->type-kDudeBase; - pSprite->x = actor->basePoint().x; - pSprite->y = actor->basePoint().y; - pSprite->z = actor->basePoint().z; + pSprite->pos = actor->basePoint; pSprite->cstat |= 0x1101; #ifdef NOONE_EXTENSIONS if (!gModernMap || pXSprite->sysData2 <= 0) pXSprite->health = dudeInfo[pSprite->type - kDudeBase].startHealth << 4; diff --git a/source/games/blood/src/gameutil.cpp b/source/games/blood/src/gameutil.cpp index c52beecdb..c0850171e 100644 --- a/source/games/blood/src/gameutil.cpp +++ b/source/games/blood/src/gameutil.cpp @@ -34,7 +34,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_BLD_NS POINT2D baseWall[kMaxWalls]; -POINT3D baseSprite[kMaxSprites]; int baseFloor[kMaxSectors]; int baseCeil[kMaxSectors]; int velFloor[kMaxSectors]; diff --git a/source/games/blood/src/gameutil.h b/source/games/blood/src/gameutil.h index 79a094fed..2209f360d 100644 --- a/source/games/blood/src/gameutil.h +++ b/source/games/blood/src/gameutil.h @@ -43,7 +43,6 @@ struct HITINFO { }; extern POINT2D baseWall[kMaxWalls]; -extern POINT3D baseSprite[kMaxSprites]; extern int baseFloor[kMaxSectors]; extern int baseCeil[kMaxSectors]; extern int velFloor[kMaxSectors]; diff --git a/source/games/blood/src/loadsave.cpp b/source/games/blood/src/loadsave.cpp index 925446362..2ec5ae186 100644 --- a/source/games/blood/src/loadsave.cpp +++ b/source/games/blood/src/loadsave.cpp @@ -484,7 +484,8 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, DBloodActor& w, DB arc("dudeslope", w.dudeSlope, def->dudeSlope) ("dudeextra", w.dudeExtra, def->dudeExtra) ("explosionflag", w.explosionhackflag, def->explosionhackflag) - ("spritehit", w.hit, def->hit); + ("spritehit", w.hit, def->hit) + ("basepoint", w.basePoint, def->basePoint); if (gModernMap) { @@ -690,7 +691,6 @@ void SerializeState(FSerializer& arc) ("frameclock", PlayClock) ("framecount", gFrameCount) .Array("basewall", baseWall, numwalls) - .SparseArray("basesprite", baseSprite, kMaxSprites, activeSprites) .Array("basefloor", baseFloor, numsectors) .Array("baseceil", baseCeil, numsectors) .Array("velfloor", velFloor, numsectors) @@ -714,12 +714,20 @@ void SerializeState(FSerializer& arc) .Array("xwall", xwall, XWallsUsed) // todo .Array("xsector", xsector, XSectorsUsed) + .SparseArray("actors", bloodActors, kMaxSprites, activeSprites) + .SparseArray("xsprite", xsprite, kMaxXSprites, activeXSprites) .SparseArray("xvel", xvel, kMaxSprites, activeSprites) .SparseArray("yvel", yvel, kMaxSprites, activeSprites) - .SparseArray("zvel", zvel, kMaxSprites, activeSprites) - .SparseArray("actors", bloodActors, kMaxSprites, activeSprites) - .EndObject(); + .SparseArray("zvel", zvel, kMaxSprites, activeSprites); + +#ifdef OLD_SAVEGAME + POINT3D baseSprite[kMaxSprites]; + for (int i = 0; i < kMaxSprites; i++) baseSprite[i] = bloodActors[i].basePoint; + arc.SparseArray("basesprite", baseSprite, kMaxSprites, activeSprites); + if (arc.isReading()) for (int i = 0; i < kMaxSprites; i++) if (activeSprites[i]) bloodActors[i].basePoint = baseSprite[i]; +#endif + arc.EndObject(); } } diff --git a/source/games/blood/src/triggers.cpp b/source/games/blood/src/triggers.cpp index e94f057a0..f75ed61a0 100644 --- a/source/games/blood/src/triggers.cpp +++ b/source/games/blood/src/triggers.cpp @@ -884,11 +884,10 @@ void TranslateSector(int nSector, int a2, int a3, int a4, int a5, int a6, int a7 } } } - int nSprite; - SectIterator it(nSector); - while ((nSprite = it.NextIndex()) >= 0) + BloodSectIterator it(nSector); + while (auto actor = it.Next()) { - spritetype *pSprite = &sprite[nSprite]; + spritetype *pSprite = &actor->s(); // allow to move markers by sector movements in game if flags 1 is added in editor. switch (pSprite->statnum) { case kStatMarker: @@ -901,22 +900,22 @@ void TranslateSector(int nSector, int a2, int a3, int a4, int a5, int a6, int a7 break; } - x = baseSprite[nSprite].x; - y = baseSprite[nSprite].y; - if (sprite[nSprite].cstat&8192) + x = actor->basePoint.x; + y = actor->basePoint.y; + if (pSprite->cstat&8192) { if (vbp) RotatePoint((int*)&x, (int*)&y, vbp, a4, a5); - viewBackupSpriteLoc(nSprite, pSprite); + viewBackupSpriteLoc(pSprite->index, pSprite); pSprite->ang = (pSprite->ang+v14)&2047; pSprite->x = x+vc-a4; pSprite->y = y+v8-a5; } - else if (sprite[nSprite].cstat&16384) + else if (pSprite->cstat&16384) { if (vbp) RotatePoint((int*)& x, (int*)& y, -vbp, a4, a4); - viewBackupSpriteLoc(nSprite, pSprite); + viewBackupSpriteLoc(pSprite->index, pSprite); pSprite->ang = (pSprite->ang-v14)&2047; pSprite->x = x-(vc-a4); pSprite->y = y-(v8-a5); @@ -930,7 +929,7 @@ void TranslateSector(int nSector, int a2, int a3, int a4, int a5, int a6, int a7 { if (v14) RotatePoint((int*)&pSprite->x, (int*)&pSprite->y, v14, v20, v24); - viewBackupSpriteLoc(nSprite, pSprite); + viewBackupSpriteLoc(pSprite->index, pSprite); pSprite->ang = (pSprite->ang+v14)&2047; pSprite->x += v28; pSprite->y += v2c; @@ -1098,30 +1097,28 @@ int VSpriteBusy(unsigned int nSector, unsigned int a2) int dz1 = pXSector->onFloorZ - pXSector->offFloorZ; if (dz1 != 0) { - int nSprite; - SectIterator it(nSector); - while ((nSprite = it.NextIndex()) >= 0) + BloodSectIterator it(nSector); + while (auto actor = it.Next()) { - spritetype *pSprite = &sprite[nSprite]; + spritetype *pSprite = &actor->s(); if (pSprite->cstat&8192) { - viewBackupSpriteLoc(nSprite, pSprite); - pSprite->z = baseSprite[nSprite].z+MulScale(dz1, GetWaveValue(a2, nWave), 16); + viewBackupSpriteLoc(pSprite->index, pSprite); + pSprite->z = actor->basePoint.z+MulScale(dz1, GetWaveValue(a2, nWave), 16); } } } int dz2 = pXSector->onCeilZ - pXSector->offCeilZ; if (dz2 != 0) { - int nSprite; - SectIterator it(nSector); - while ((nSprite = it.NextIndex()) >= 0) + BloodSectIterator it(nSector); + while (auto actor = it.Next()) { - spritetype *pSprite = &sprite[nSprite]; - if (pSprite->cstat&16384) + spritetype* pSprite = &actor->s(); + if (pSprite->cstat & 16384) { - viewBackupSpriteLoc(nSprite, pSprite); - pSprite->z = baseSprite[nSprite].z+MulScale(dz2, GetWaveValue(a2, nWave), 16); + viewBackupSpriteLoc(pSprite->index, pSprite); + pSprite->z = actor->basePoint.z + MulScale(dz2, GetWaveValue(a2, nWave), 16); } } } @@ -2006,17 +2003,15 @@ void trInit(void) baseWall[i].x = wall[i].x; baseWall[i].y = wall[i].y; } - for (int i = 0; i < kMaxSprites; i++) + BloodLinearSpriteIterator it; + while (auto actor = it.Next()) { - if (sprite[i].statnum < kStatFree) + auto spr = &actor->s(); + if (spr->statnum < kStatFree) { - sprite[i].inittype = sprite[i].type; - baseSprite[i].x = sprite[i].x; - baseSprite[i].y = sprite[i].y; - baseSprite[i].z = sprite[i].z; + spr->inittype = spr->type; + actor->basePoint = spr->pos; } - else - sprite[i].inittype = -1; } for (int i = 0; i < numwalls; i++) { @@ -2068,13 +2063,10 @@ void trInit(void) baseWall[pSector->wallptr+j].x = wall[pSector->wallptr+j].x; baseWall[pSector->wallptr+j].y = wall[pSector->wallptr+j].y; } - int nSprite; - SectIterator it(i); - while ((nSprite = it.NextIndex()) >= 0) + BloodSectIterator it(i); + while (auto actor = it.Next()) { - baseSprite[nSprite].x = sprite[nSprite].x; - baseSprite[nSprite].y = sprite[nSprite].y; - baseSprite[nSprite].z = sprite[nSprite].z; + actor->basePoint = actor->s().pos; } TranslateSector(i, 0, pXSector->busy, pSprite1->x, pSprite1->y, pSprite1->x, pSprite1->y, pSprite1->ang, pSprite2->x, pSprite2->y, pSprite2->ang, pSector->type == kSectorSlide); ZTranslateSector(i, pXSector, pXSector->busy, 1); @@ -2090,13 +2082,10 @@ void trInit(void) baseWall[pSector->wallptr+j].x = wall[pSector->wallptr+j].x; baseWall[pSector->wallptr+j].y = wall[pSector->wallptr+j].y; } - int nSprite; - SectIterator it(i); - while ((nSprite = it.NextIndex()) >= 0) + BloodSectIterator it(i); + while (auto actor = it.Next()) { - baseSprite[nSprite].x = sprite[nSprite].x; - baseSprite[nSprite].y = sprite[nSprite].y; - baseSprite[nSprite].z = sprite[nSprite].z; + actor->basePoint = actor->s().pos; } TranslateSector(i, 0, pXSector->busy, pSprite1->x, pSprite1->y, pSprite1->x, pSprite1->y, 0, pSprite1->x, pSprite1->y, pSprite1->ang, pSector->type == kSectorRotate); ZTranslateSector(i, pXSector, pXSector->busy, 1);