diff --git a/source/blood/src/ai.cpp b/source/blood/src/ai.cpp index a61a3357c..6d1fb79cb 100644 --- a/source/blood/src/ai.cpp +++ b/source/blood/src/ai.cpp @@ -52,7 +52,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_BLD_NS int cumulDamage[kMaxXSprites]; -int gDudeSlope[kMaxXSprites]; DUDEEXTRA gDudeExtra[kMaxXSprites]; AISTATE genIdle = {kAiStateGenIdle, 0, -1, 0, NULL, NULL, NULL, NULL }; @@ -1793,8 +1792,7 @@ void SerializeAI(FSerializer& arc) { if (arc.BeginObject("ai")) { - arc.SparseArray("dudeslope", gDudeSlope, kMaxSprites, activeXSprites) - .SparseArray("dudeextra", gDudeExtra, kMaxSprites, activeXSprites) + arc.SparseArray("dudeextra", gDudeExtra, kMaxSprites, activeXSprites) .EndObject(); } } diff --git a/source/blood/src/ai.h b/source/blood/src/ai.h index 16016a776..5061ce60e 100644 --- a/source/blood/src/ai.h +++ b/source/blood/src/ai.h @@ -89,7 +89,6 @@ struct TARGETTRACK { extern const int dword_138BB0[5]; extern DUDEEXTRA gDudeExtra[]; extern int gDudeSlope[]; -extern int cumulDamage[]; bool dudeIsPlayingSeq(spritetype *pSprite, int nSeq); void aiPlay3DSound(spritetype *pSprite, int a2, AI_SFX_PRIORITY a3, int a4); diff --git a/source/blood/src/aibeast.cpp b/source/blood/src/aibeast.cpp index 5d1c1efbc..813220be3 100644 --- a/source/blood/src/aibeast.cpp +++ b/source/blood/src/aibeast.cpp @@ -293,7 +293,7 @@ static void beastThinkChase(DBloodActor* actor) if (nDist < pDudeInfo->seeDist && klabs(nDeltaAngle) <= pDudeInfo->periphery) { aiSetTarget(pXSprite, pXSprite->target); - actor->dudeSlope() = divscale(pTarget->z-pSprite->z, nDist, 10); + actor->dudeSlope = divscale(pTarget->z-pSprite->z, nDist, 10); if (nDist < 0x1400 && nDist > 0xa00 && klabs(nDeltaAngle) < 85 && (pTarget->flags&2) && IsPlayerSprite(pTarget) && Chance(0x8000)) { diff --git a/source/blood/src/aicaleb.cpp b/source/blood/src/aicaleb.cpp index 8f9a5d62c..8f66d6504 100644 --- a/source/blood/src/aicaleb.cpp +++ b/source/blood/src/aicaleb.cpp @@ -75,7 +75,7 @@ void SeqAttackCallback(int, DBloodActor* actor) spritetype *pSprite = &actor->s(); int dx = CosScale16(pSprite->ang); int dy = SinScale16(pSprite->ang); - int dz = actor->dudeSlope(); + int dz = actor->dudeSlope; dx += Random2(1500); dy += Random2(1500); dz += Random2(1500); @@ -196,7 +196,7 @@ static void calebThinkChase(DBloodActor* actor) if (nDist < pDudeInfo->seeDist && klabs(nDeltaAngle) <= pDudeInfo->periphery) { aiSetTarget(pXSprite, pXSprite->target); - actor->dudeSlope() = divscale(pTarget->z-pSprite->z, nDist, 10); + actor->dudeSlope = divscale(pTarget->z-pSprite->z, nDist, 10); if (nDist < 0x599 && klabs(nDeltaAngle) < 28) { XSECTOR *pXSector; diff --git a/source/blood/src/aicerber.cpp b/source/blood/src/aicerber.cpp index 3f14fda65..036318ca9 100644 --- a/source/blood/src/aicerber.cpp +++ b/source/blood/src/aicerber.cpp @@ -109,7 +109,7 @@ void cerberusBurnSeqCallback(int, DBloodActor* actor) Aim aim; aim.dx = CosScale16(pSprite->ang); aim.dy = SinScale16(pSprite->ang); - aim.dz = actor->dudeSlope(); + aim.dz = actor->dudeSlope; int nClosest = 0x7fffffff; int nSprite2; StatIterator it(kStatDude); @@ -133,7 +133,7 @@ void cerberusBurnSeqCallback(int, DBloodActor* actor) } int tx = x+mulscale30(Cos(pSprite->ang), nDist); int ty = y+mulscale30(Sin(pSprite->ang), nDist); - int tz = z+mulscale(actor->dudeSlope(), nDist, 10); + int tz = z+mulscale(actor->dudeSlope, nDist, 10); int tsr = mulscale(9460, nDist, 10); int top, bottom; GetSpriteExtents(pSprite2, &top, &bottom); @@ -193,7 +193,7 @@ void cerberusBurnSeqCallback2(int, DBloodActor* actor) int ax, ay, az; aim.dx = ax = CosScale16(pSprite->ang); aim.dy = ay = SinScale16(pSprite->ang); - aim.dz = actor->dudeSlope(); + aim.dz = actor->dudeSlope; az = 0; int nClosest = 0x7fffffff; int nSprite2; @@ -218,7 +218,7 @@ void cerberusBurnSeqCallback2(int, DBloodActor* actor) } int tx = x+mulscale30(Cos(pSprite->ang), nDist); int ty = y+mulscale30(Sin(pSprite->ang), nDist); - int tz = z+mulscale(actor->dudeSlope(), nDist, 10); + int tz = z+mulscale(actor->dudeSlope, nDist, 10); int tsr = mulscale(9460, nDist, 10); int top, bottom; GetSpriteExtents(pSprite2, &top, &bottom); diff --git a/source/blood/src/aicult.cpp b/source/blood/src/aicult.cpp index 6783f800a..ca8b6d7d8 100644 --- a/source/blood/src/aicult.cpp +++ b/source/blood/src/aicult.cpp @@ -93,7 +93,7 @@ void TommySeqCallback(int, DBloodActor* actor) spritetype* pSprite = &actor->s(); int dx = CosScale16(pSprite->ang); int dy = SinScale16(pSprite->ang); - int dz = actor->dudeSlope(); + int dz = actor->dudeSlope; dx += Random3((5-gGameOptions.nDifficulty)*1000); dy += Random3((5-gGameOptions.nDifficulty)*1000); dz += Random3((5-gGameOptions.nDifficulty)*500); @@ -109,7 +109,7 @@ void TeslaSeqCallback(int, DBloodActor* actor) { int dx = CosScale16(pSprite->ang); int dy = SinScale16(pSprite->ang); - int dz = actor->dudeSlope(); + int dz = actor->dudeSlope; dx += Random3((5-gGameOptions.nDifficulty)*1000); dy += Random3((5-gGameOptions.nDifficulty)*1000); dz += Random3((5-gGameOptions.nDifficulty)*500); @@ -124,7 +124,7 @@ void ShotSeqCallback(int, DBloodActor* actor) spritetype* pSprite = &actor->s(); int dx = CosScale16(pSprite->ang); int dy = SinScale16(pSprite->ang); - int dz = actor->dudeSlope(); + int dz = actor->dudeSlope; dx += Random2((5-gGameOptions.nDifficulty)*1000-500); dy += Random2((5-gGameOptions.nDifficulty)*1000-500); dz += Random2((5-gGameOptions.nDifficulty)*500); @@ -175,7 +175,7 @@ void sub_68170(int, DBloodActor* actor) if (gGameOptions.nDifficulty > 2) nMissile = kThingArmedTNTBundle; sfxPlay3DSound(pSprite, 455, -1, 0); - spritetype* pMissile = actFireThing(pSprite, 0, 0, actor->dudeSlope() - 9460, nMissile, 0x133333); + spritetype* pMissile = actFireThing(pSprite, 0, 0, actor->dudeSlope - 9460, nMissile, 0x133333); evPost(pMissile->index, 3, 120*(2+Random(2)), kCmdOn); } @@ -314,7 +314,7 @@ static void cultThinkChase(DBloodActor* actor) if (nDist < pDudeInfo->seeDist && klabs(nDeltaAngle) <= pDudeInfo->periphery) { aiSetTarget(pXSprite, pXSprite->target); - actor->dudeSlope() = divscale(pTarget->z-pSprite->z, nDist, 10); + actor->dudeSlope = divscale(pTarget->z-pSprite->z, nDist, 10); switch (pSprite->type) { case kDudeCultistTommy: if (nDist < 0x1e00 && nDist > 0xe00 && klabs(nDeltaAngle) < 85 && !TargetNearExplosion(pTarget) diff --git a/source/blood/src/aigarg.cpp b/source/blood/src/aigarg.cpp index 15266d0c4..81b1dab30 100644 --- a/source/blood/src/aigarg.cpp +++ b/source/blood/src/aigarg.cpp @@ -117,7 +117,7 @@ void ThrowFSeqCallback(int, DBloodActor* actor) { XSPRITE* pXSprite = &actor->x(); spritetype* pSprite = &actor->s(); - actFireThing(&actor->s(), 0, 0, actor->dudeSlope()-7500, kThingBone, 0xeeeee); + actFireThing(&actor->s(), 0, 0, actor->dudeSlope-7500, kThingBone, 0xeeeee); } void BlastSSeqCallback(int, DBloodActor* actor) @@ -136,7 +136,7 @@ void BlastSSeqCallback(int, DBloodActor* actor) Aim aim; aim.dx = CosScale16(pSprite->ang); aim.dy = SinScale16(pSprite->ang); - aim.dz = actor->dudeSlope(); + aim.dz = actor->dudeSlope; int nClosest = 0x7fffffff; int nSprite2; StatIterator it(kStatDude); @@ -160,7 +160,7 @@ void BlastSSeqCallback(int, DBloodActor* actor) } int tx = x+mulscale30(Cos(pSprite->ang), nDist); int ty = y+mulscale30(Sin(pSprite->ang), nDist); - int tz = z+mulscale(actor->dudeSlope(), nDist, 10); + int tz = z+mulscale(actor->dudeSlope, nDist, 10); int tsr = mulscale(9460, nDist, 10); int top, bottom; GetSpriteExtents(pSprite2, &top, &bottom); @@ -217,7 +217,7 @@ void BlastSSeqCallback(int, DBloodActor* actor) void ThrowSSeqCallback(int, DBloodActor* actor) { spritetype* pSprite = &actor->s(); - actFireThing(pSprite, 0, 0, actor->dudeSlope() - 7500, kThingBone, Chance(0x6000) ? 0x133333 : 0x111111); + actFireThing(pSprite, 0, 0, actor->dudeSlope - 7500, kThingBone, Chance(0x6000) ? 0x133333 : 0x111111); } static void gargThinkTarget(DBloodActor* actor) diff --git a/source/blood/src/aighost.cpp b/source/blood/src/aighost.cpp index 5f28b72ed..6170b64de 100644 --- a/source/blood/src/aighost.cpp +++ b/source/blood/src/aighost.cpp @@ -100,7 +100,7 @@ void ghostSlashSeqCallback(int, DBloodActor* actor) void ghostThrowSeqCallback(int, DBloodActor* actor) { - actFireThing(&actor->s(), 0, 0, actor->dudeSlope() - 7500, kThingBone, 0xeeeee); + actFireThing(&actor->s(), 0, 0, actor->dudeSlope - 7500, kThingBone, 0xeeeee); } void ghostBlastSeqCallback(int, DBloodActor* actor) @@ -119,7 +119,7 @@ void ghostBlastSeqCallback(int, DBloodActor* actor) Aim aim; aim.dx = CosScale16(pSprite->ang); aim.dy = SinScale16(pSprite->ang); - aim.dz = actor->dudeSlope(); + aim.dz = actor->dudeSlope; int nClosest = 0x7fffffff; int nSprite2; StatIterator it(kStatDude); @@ -143,7 +143,7 @@ void ghostBlastSeqCallback(int, DBloodActor* actor) } int tx = x+mulscale30(Cos(pSprite->ang), nDist); int ty = y+mulscale30(Sin(pSprite->ang), nDist); - int tz = z+mulscale(actor->dudeSlope(), nDist, 10); + int tz = z+mulscale(actor->dudeSlope, nDist, 10); int tsr = mulscale(9460, nDist, 10); int top, bottom; GetSpriteExtents(pSprite2, &top, &bottom); diff --git a/source/blood/src/aigilbst.cpp b/source/blood/src/aigilbst.cpp index 9e8ebfff5..cf21bcfbd 100644 --- a/source/blood/src/aigilbst.cpp +++ b/source/blood/src/aigilbst.cpp @@ -185,7 +185,7 @@ static void gillThinkChase(DBloodActor* actor) if (nDist < pDudeInfo->seeDist && klabs(nDeltaAngle) <= pDudeInfo->periphery) { aiSetTarget(pXSprite, pXSprite->target); - actor->dudeSlope() = divscale(pTarget->z-pSprite->z, nDist, 10); + actor->dudeSlope = divscale(pTarget->z-pSprite->z, nDist, 10); if (nDist < 921 && klabs(nDeltaAngle) < 28) { XSECTOR *pXSector; diff --git a/source/blood/src/aitchern.cpp b/source/blood/src/aitchern.cpp index a67e25fd1..7b5f88385 100644 --- a/source/blood/src/aitchern.cpp +++ b/source/blood/src/aitchern.cpp @@ -93,7 +93,7 @@ void sub_71BD4(int, DBloodActor* actor) Aim aim; aim.dx = CosScale16(pSprite->ang); aim.dy = SinScale16(pSprite->ang); - aim.dz = actor->dudeSlope(); + aim.dz = actor->dudeSlope; int nClosest = 0x7fffffff; int nSprite2; StatIterator it(kStatDude); @@ -117,7 +117,7 @@ void sub_71BD4(int, DBloodActor* actor) } int tx = x+mulscale30(Cos(pSprite->ang), nDist); int ty = y+mulscale30(Sin(pSprite->ang), nDist); - int tz = z+mulscale(actor->dudeSlope(), nDist, 10); + int tz = z+mulscale(actor->dudeSlope, nDist, 10); int tsr = mulscale(9460, nDist, 10); int top, bottom; GetSpriteExtents(pSprite2, &top, &bottom); @@ -171,7 +171,7 @@ void sub_720AC(int, DBloodActor* actor) Aim aim; aim.dx = ax; aim.dy = ay; - aim.dz = actor->dudeSlope(); + aim.dz = actor->dudeSlope; int nClosest = 0x7fffffff; az = 0; int nSprite2; @@ -196,7 +196,7 @@ void sub_720AC(int, DBloodActor* actor) } int tx = x+mulscale30(Cos(pSprite->ang), nDist); int ty = y+mulscale30(Sin(pSprite->ang), nDist); - int tz = z+mulscale(actor->dudeSlope(), nDist, 10); + int tz = z+mulscale(actor->dudeSlope, nDist, 10); int tsr = mulscale(9460, nDist, 10); int top, bottom; GetSpriteExtents(pSprite2, &top, &bottom); diff --git a/source/blood/src/aiunicult.cpp b/source/blood/src/aiunicult.cpp index 06070932e..d8b38409f 100644 --- a/source/blood/src/aiunicult.cpp +++ b/source/blood/src/aiunicult.cpp @@ -166,12 +166,12 @@ static bool genDudeAdjustSlope(DBloodActor* actor, int dist, int weaponType, int { if (weaponType == kGenDudeWeaponHitscan) { - actor->dudeSlope() = fStart - ((fStart - fEnd) >> 2); + actor->dudeSlope = fStart - ((fStart - fEnd) >> 2); } else if (weaponType == kGenDudeWeaponMissile) { const MissileType* pMissile = &missileInfo[pExtra->curWeapon - kMissileBase]; - actor->dudeSlope() = (fStart - ((fStart - fEnd) >> 2)) - (pMissile->clipDist << 1); + actor->dudeSlope = (fStart - ((fStart - fEnd) >> 2)) - (pMissile->clipDist << 1); } return true; @@ -234,7 +234,7 @@ void genDudeAttack1(int, DBloodActor* actor) if (pExtra->weaponType == kGenDudeWeaponHitscan) { - dx = CosScale16(pSprite->ang); dy = SinScale16(pSprite->ang); dz = actor->dudeSlope(); + dx = CosScale16(pSprite->ang); dy = SinScale16(pSprite->ang); dz = actor->dudeSlope; // dispersal modifiers here in case if non-melee enemy if (!dudeIsMelee(pXSprite)) { dx += Random3(dispersion); dy += Random3(dispersion); dz += Random3(dispersion); @@ -266,7 +266,7 @@ void genDudeAttack1(int, DBloodActor* actor) } else if (pExtra->weaponType == kGenDudeWeaponMissile) { - dx = CosScale16(pSprite->ang); dy = SinScale16(pSprite->ang); dz = actor->dudeSlope(); + dx = CosScale16(pSprite->ang); dy = SinScale16(pSprite->ang); dz = actor->dudeSlope; // dispersal modifiers here dx += Random3(dispersion); dy += Random3(dispersion); dz += Random3(dispersion >> 1); @@ -513,7 +513,7 @@ static void unicultThinkChase(DBloodActor* actor) if ((gFrameClock & 64) == 0 && Chance(0x3000) && !spriteIsUnderwater(pSprite, false)) playGenDudeSound(pSprite, kGenDudeSndChasing); - actor->dudeSlope() = divscale(pTarget->z - pSprite->z, dist, 10); + actor->dudeSlope = divscale(pTarget->z - pSprite->z, dist, 10); short curWeapon = gGenDudeExtra[pSprite->index].curWeapon; short weaponType = gGenDudeExtra[pSprite->index].weaponType; spritetype* pLeech = leechIsDropped(pSprite); const VECTORDATA* meleeVector = &gVectorData[22]; @@ -682,9 +682,9 @@ static void unicultThinkChase(DBloodActor* actor) if (pExtra->canWalk) { int objDist = -1; int targetDist = -1; int hit = -1; if (weaponType == kGenDudeWeaponHitscan) - hit = HitScan(pSprite, pSprite->z, CosScale16(pSprite->ang), SinScale16(pSprite->ang), actor->dudeSlope(), CLIPMASK1, dist); + hit = HitScan(pSprite, pSprite->z, CosScale16(pSprite->ang), SinScale16(pSprite->ang), actor->dudeSlope, CLIPMASK1, dist); else if (weaponType == kGenDudeWeaponMissile) - hit = HitScan(pSprite, pSprite->z, CosScale16(pSprite->ang), SinScale16(pSprite->ang), actor->dudeSlope(), CLIPMASK0, dist); + hit = HitScan(pSprite, pSprite->z, CosScale16(pSprite->ang), SinScale16(pSprite->ang), actor->dudeSlope, CLIPMASK0, dist); if (hit >= 0) { targetDist = dist - (pTarget->clipdist << 2); @@ -787,7 +787,7 @@ static void unicultThinkChase(DBloodActor* actor) else if (weaponType == kGenDudeWeaponHitscan && hscn) { if (genDudeAdjustSlope(actor, dist, weaponType)) break; - VectorScan(pSprite, 0, 0, CosScale16(pSprite->ang), SinScale16(pSprite->ang), actor->dudeSlope(), dist, 1); + VectorScan(pSprite, 0, 0, CosScale16(pSprite->ang), SinScale16(pSprite->ang), actor->dudeSlope, dist, 1); if (pXSprite->target == gHitInfo.hitsprite) break; bool immune = nnExtIsImmune(pHSprite, gVectorData[curWeapon].dmgType); @@ -839,7 +839,7 @@ static void unicultThinkChase(DBloodActor* actor) case 4: if (hit == 4 && weaponType == kGenDudeWeaponHitscan && hscn) { bool masked = (pHWall->cstat & CSTAT_WALL_MASKED); - if (masked) VectorScan(pSprite, 0, 0, CosScale16(pSprite->ang), SinScale16(pSprite->ang), actor->dudeSlope(), dist, 1); + if (masked) VectorScan(pSprite, 0, 0, CosScale16(pSprite->ang), SinScale16(pSprite->ang), actor->dudeSlope, dist, 1); //viewSetSystemMessage("WALL VHIT: %d", gHitInfo.hitwall); if ((pXSprite->target != gHitInfo.hitsprite) && (pHWall->type != kWallGib || !masked || pXHWall == NULL || !pXHWall->triggerVector || pXHWall->locked)) { diff --git a/source/blood/src/bloodactor.h b/source/blood/src/bloodactor.h index ae79494be..8b9e969e1 100644 --- a/source/blood/src/bloodactor.h +++ b/source/blood/src/bloodactor.h @@ -10,15 +10,20 @@ BEGIN_BLD_NS +extern int cumulDamage[kMaxXSprites]; + // Due to the messed up array storage of all the game data we cannot do any direct references here yet. We have to access everything via wrapper functions for now. // Note that the indexing is very inconsistent - partially by sprite index, partially by xsprite index. class DBloodActor { - const int index; + int index; DBloodActor* base(); public: - DBloodActor() :index(int(this - base())) { assert(index >= 0 && index < kMaxSprites); } + int dudeSlope; + + DBloodActor() :index(int(this - base())) { /*assert(index >= 0 && index < kMaxSprites);*/ } + DBloodActor& operator=(const DBloodActor& other) = default; bool hasX() { return sprite[index].extra > 0; } spritetype& s() { return sprite[index]; } @@ -29,7 +34,6 @@ public: int& zvel() { return Blood::zvel[index]; } int& cumulDamage() { return Blood::cumulDamage[sprite[index].extra]; } - int& dudeSlope() { return Blood::gDudeSlope[sprite[index].extra]; } DUDEEXTRA& dudeExtra() { return gDudeExtra[sprite[index].extra]; } SPRITEMASS& spriteMass() { return gSpriteMass[sprite[index].extra]; } GENDUDEEXTRA& genDudeExtra() { return Blood::gGenDudeExtra[index]; } diff --git a/source/blood/src/loadsave.cpp b/source/blood/src/loadsave.cpp index 0e78719ff..6b82566fc 100644 --- a/source/blood/src/loadsave.cpp +++ b/source/blood/src/loadsave.cpp @@ -43,6 +43,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "mapinfo.h" #include "gamestate.h" #include "d_net.h" +#include "bloodactor.h" #include "aistate.h" #include "aiunicult.h" @@ -436,6 +437,28 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, AISTATE*& w, AISTA return arc; } +FSerializer& Serialize(FSerializer& arc, const char* keyname, DBloodActor& w, DBloodActor* def) +{ + static DBloodActor nul; + if (!def) + { + def = &nul; + if (arc.isReading()) w = {}; + } + + if (arc.BeginObject(keyname)) + { + + // The rest is only relevant if the actor has an xsprite. + if (w.s().extra > 0) + { + arc("dudeslope", w.dudeSlope, def->dudeSlope); + } + arc.EndObject(); + } + return arc; +} + FSerializer& Serialize(FSerializer& arc, const char* keyname, XWALL& w, XWALL* def) { static XWALL nul; @@ -646,6 +669,7 @@ void SerializeState(FSerializer& arc) .SparseArray("xvel", xvel, kMaxSprites, activeSprites) .SparseArray("yvel", yvel, kMaxSprites, activeSprites) .SparseArray("zvel", zvel, kMaxSprites, activeSprites) + .SparseArray("actors", bloodActors, kMaxSprites, activeSprites) .EndObject(); } } diff --git a/source/blood/src/nnexts.cpp b/source/blood/src/nnexts.cpp index 9c107de2b..ee4b75ffd 100644 --- a/source/blood/src/nnexts.cpp +++ b/source/blood/src/nnexts.cpp @@ -3094,7 +3094,7 @@ bool condCheckSprite(XSPRITE* pXCond, int cmpOp, bool PUSH) { if ((pPlayer = getPlayerById(pSpr->type)) != NULL) var = HitScan(pSpr, pPlayer->zWeapon - pSpr->z, pPlayer->aim.dx, pPlayer->aim.dy, pPlayer->aim.dz, arg1, arg3 << 1); else if (IsDudeSprite(pSpr)) - var = HitScan(pSpr, pSpr->z, CosScale16(pSpr->ang), SinScale16(pSpr->ang), actor->dudeSlope(), arg1, arg3 << 1); + var = HitScan(pSpr, pSpr->z, CosScale16(pSpr->ang), SinScale16(pSpr->ang), actor->dudeSlope, arg1, arg3 << 1); else var = HitScan(pSpr, pSpr->z, CosScale16(pSpr->ang), SinScale16(pSpr->ang), 0, arg1, arg3 << 1);