From 9221262dfcd2848442d260a78c1ad91cd852cb34 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 2 Sep 2021 20:23:51 +0200 Subject: [PATCH] - refactoring of all getzrange code to use the Collision struct. --- source/games/blood/src/actor.cpp | 111 +++++++++------ source/games/blood/src/aiunicult.cpp | 2 +- source/games/blood/src/animatesprite.cpp | 5 +- source/games/blood/src/bloodactor.h | 170 +++++++++++++---------- source/games/blood/src/callback.cpp | 18 ++- source/games/blood/src/db.h | 6 - source/games/blood/src/gameutil.cpp | 41 +++--- source/games/blood/src/gameutil.h | 6 +- source/games/blood/src/nnexts.cpp | 129 ++++++++++------- source/games/blood/src/player.cpp | 10 +- source/games/blood/src/prediction.cpp | 37 ++--- source/games/blood/src/view.cpp | 8 +- source/games/blood/src/view.h | 7 +- 13 files changed, 319 insertions(+), 231 deletions(-) diff --git a/source/games/blood/src/actor.cpp b/source/games/blood/src/actor.cpp index 98130f231..c4646444e 100644 --- a/source/games/blood/src/actor.cpp +++ b/source/games/blood/src/actor.cpp @@ -4548,12 +4548,11 @@ static void ProcessTouchObjects(DBloodActor* actor) if (gModernMap && actor->IsDudeActor()) { DBloodActor* actor2 = nullptr; - for (int i : { actor->hit().hit, actor->hit().florhit, actor->hit().ceilhit}) + for (Collision* coll : { &actor->hit().hit, &actor->hit().florhit, &actor->hit().ceilhit}) { - Collision coll = i; - if (coll.type == kHitSprite) + if (coll->type == kHitSprite) { - actor2 = coll.actor; + actor2 = coll->actor; break; } } @@ -4625,18 +4624,19 @@ void actAirDrag(DBloodActor* actor, int a2) // //--------------------------------------------------------------------------- -int MoveThing(DBloodActor* actor) +static Collision MoveThing(DBloodActor* actor) { auto pSprite = &actor->s(); assert(actor->hasX()); XSPRITE* pXSprite = &actor->x(); - int lhit = 0; assert(pSprite->type >= kThingBase && pSprite->type < kThingMax); const THINGINFO* pThingInfo = &thingInfo[pSprite->type - kThingBase]; int nSector = pSprite->sectnum; assert(nSector >= 0 && nSector < kMaxSectors); int top, bottom; + Collision lhit; + lhit.setNone(); GetActorExtents(actor, &top, &bottom); const int bakCompat = enginecompatibility_mode; if (actor->xvel() || actor->yvel()) @@ -4655,7 +4655,7 @@ int MoveThing(DBloodActor* actor) ChangeActorSect(actor, nSector); } - Collision coll(actor->hit().hit); + Collision &coll = actor->hit().hit; if (coll.type == kHitWall) { int nHitWall = coll.index; @@ -4681,8 +4681,9 @@ int MoveThing(DBloodActor* actor) pSprite->z += actor->zvel() >> 8; - int ceilZ, ceilHit, floorZ, floorHit; - GetZRange(pSprite, &ceilZ, &ceilHit, &floorZ, &floorHit, pSprite->clipdist << 2, CLIPMASK0); + int ceilZ, floorZ; + Collision ceilColl, floorColl; + GetZRange(pSprite, &ceilZ, &ceilColl, &floorZ, &floorColl, pSprite->clipdist << 2, CLIPMASK0); GetActorExtents(actor, &top, &bottom); if ((pSprite->flags & 2) && bottom < floorZ) @@ -4709,13 +4710,13 @@ int MoveThing(DBloodActor* actor) } } } - if (CheckLink(pSprite)) GetZRange(pSprite, &ceilZ, &ceilHit, &floorZ, &floorHit, pSprite->clipdist << 2, CLIPMASK0); + if (CheckLink(pSprite)) GetZRange(pSprite, &ceilZ, &ceilColl, &floorZ, &floorColl, pSprite->clipdist << 2, CLIPMASK0); GetActorExtents(actor, &top, &bottom); if (bottom >= floorZ) { actTouchFloor(actor, pSprite->sectnum); - actor->hit().florhit = floorHit; + actor->hit().florhit = floorColl; pSprite->z += floorZ - bottom; int v20 = actor->zvel() - velFloor[pSprite->sectnum]; @@ -4770,7 +4771,7 @@ int MoveThing(DBloodActor* actor) if (top <= ceilZ) { - actor->hit().ceilhit = ceilHit; + actor->hit().ceilhit = ceilColl; pSprite->z += ClipLow(ceilZ - top, 0); if (actor->zvel() < 0) { @@ -4801,7 +4802,7 @@ int MoveThing(DBloodActor* actor) { int nVel = approxDist(actor->xvel(), actor->yvel()); int nVelClipped = ClipHigh(nVel, 0x11111); - Collision coll(floorHit); + Collision& coll = floorColl; if (coll.type == kHitSprite) { @@ -4887,8 +4888,8 @@ void MoveDude(DBloodActor* actor) assert(nSector >= 0); pSprite->cstat = bakCstat; } - Collision coll = actor->hit().hit; - switch (actor->hit().hit & 0xc000) + const Collision& coll = actor->hit().hit; + switch (coll.type) { case kHitSprite: { @@ -4991,8 +4992,9 @@ void MoveDude(DBloodActor* actor) if (pPlayer) wd += 16; if (actor->zvel()) pSprite->z += actor->zvel() >> 8; - int ceilZ, ceilHit, floorZ, floorHit; - GetZRange(pSprite, &ceilZ, &ceilHit, &floorZ, &floorHit, wd, CLIPMASK0, PARALLAXCLIP_CEILING | PARALLAXCLIP_FLOOR); + int ceilZ, floorZ; + Collision ceilColl, floorColl; + GetZRange(pSprite, &ceilZ, &ceilColl, &floorZ, &floorColl, wd, CLIPMASK0, PARALLAXCLIP_CEILING | PARALLAXCLIP_FLOOR); GetActorExtents(actor, &top, &bottom); if (pSprite->flags & 2) @@ -5041,7 +5043,7 @@ void MoveDude(DBloodActor* actor) int nLink = CheckLink(pSprite); if (nLink) { - GetZRange(pSprite, &ceilZ, &ceilHit, &floorZ, &floorHit, wd, CLIPMASK0, PARALLAXCLIP_CEILING | PARALLAXCLIP_FLOOR); + GetZRange(pSprite, &ceilZ, &ceilColl, &floorZ, &floorColl, wd, CLIPMASK0, PARALLAXCLIP_CEILING | PARALLAXCLIP_FLOOR); if (pPlayer) playerCorrectInertia(pPlayer, &oldpos); switch (nLink) @@ -5204,17 +5206,17 @@ void MoveDude(DBloodActor* actor) if (pPlayer && bottom >= floorZ) { int floorZ2 = floorZ; - int floorHit2 = floorHit; - GetZRange(pSprite, &ceilZ, &ceilHit, &floorZ, &floorHit, pSprite->clipdist << 2, CLIPMASK0, PARALLAXCLIP_CEILING | PARALLAXCLIP_FLOOR); + auto floorColl2 = floorColl; + GetZRange(pSprite, &ceilZ, &ceilColl, &floorZ, &floorColl, pSprite->clipdist << 2, CLIPMASK0, PARALLAXCLIP_CEILING | PARALLAXCLIP_FLOOR); if (bottom <= floorZ && pSprite->z - floorZ2 < bz) { floorZ = floorZ2; - floorHit = floorHit2; + floorColl = floorColl2; } } if (floorZ <= bottom) { - actor->hit().florhit = floorHit; + actor->hit().florhit = floorColl; pSprite->z += floorZ - bottom; int v30 = actor->zvel() - velFloor[pSprite->sectnum]; if (v30 > 0) @@ -5237,13 +5239,12 @@ void MoveDude(DBloodActor* actor) if (abs(actor->zvel()) < 0x10000) { actor->zvel() = velFloor[pSprite->sectnum]; - pSprite->flags &= ~4; } else pSprite->flags |= 4; - switch (tileGetSurfType(floorHit)) + switch (tileGetSurfType(floorColl.legacyVal)) { case kSurfWater: gFX.fxSpawnActor(FX_9, pSprite->sectnum, pSprite->x, pSprite->y, floorZ, 0); @@ -5282,7 +5283,7 @@ void MoveDude(DBloodActor* actor) } if (top <= ceilZ) { - actor->hit().ceilhit = ceilHit; + actor->hit().ceilhit = ceilColl; pSprite->z += ClipLow(ceilZ - top, 0); if (actor->zvel() <= 0 && (pSprite->flags & 4)) @@ -5296,10 +5297,9 @@ void MoveDude(DBloodActor* actor) pXSprite->height = ClipLow(floorZ - bottom, 0) >> 8; if (actor->xvel() || actor->yvel()) { - Collision coll = floorHit; - if (coll.type == kHitSprite) + if (floorColl.type == kHitSprite) { - auto hitAct = coll.actor; + auto hitAct = floorColl.actor; if ((hitAct->s().cstat & 0x30) == 0) { actor->xvel() += MulScale(4, pSprite->x - hitAct->s().x, 2); @@ -5443,20 +5443,21 @@ int MoveMissile(DBloodActor* actor) updatesector(pos.x, pos.y, &nSector); nSector2 = nSector; } - int ceilZ, ceilHit, floorZ, floorHit; - GetZRangeAtXYZ(pos.x, pos.y, pos.z, nSector2, &ceilZ, &ceilHit, &floorZ, &floorHit, pSprite->clipdist << 2, CLIPMASK0); + int ceilZ, floorZ; + Collision ceilColl, floorColl; + GetZRangeAtXYZ(pos.x, pos.y, pos.z, nSector2, &ceilZ, &ceilColl, &floorZ, &floorColl, pSprite->clipdist << 2, CLIPMASK0); GetActorExtents(actor, &top, &bottom); top += vz; bottom += vz; if (bottom >= floorZ) { - actor->hit().florhit = floorHit; + actor->hit().florhit = floorColl; vz += floorZ - bottom; cliptype = 2; } if (top <= ceilZ) { - actor->hit().ceilhit = ceilHit; + actor->hit().ceilhit = ceilColl; vz += ClipLow(ceilZ - top, 0); cliptype = 1; } @@ -5527,7 +5528,7 @@ void actExplodeSprite(DBloodActor* actor) case kThingArmedTNTStick: nType = kExplosionSmall; - if (actor->hit().florhit == 0) seqSpawn(4, actor, -1); + if (actor->hit().florhit.type == kHitNone) seqSpawn(4, actor, -1); else seqSpawn(3, actor, -1); sfxPlay3DSound(actor, 303, -1, 0); GibSprite(pSprite, GIBTYPE_5, nullptr, nullptr); @@ -5540,7 +5541,7 @@ void actExplodeSprite(DBloodActor* actor) case kModernThingTNTProx: #endif nType = kExplosionStandard; - if (actor->hit().florhit == 0) seqSpawn(4, actor, -1); + if (actor->hit().florhit.type == kHitNone) seqSpawn(4, actor, -1); else seqSpawn(3, actor, -1); sfxPlay3DSound(actor, 304, -1, 0); @@ -7340,7 +7341,7 @@ void MakeSplash(DBloodActor* actor) pSprite->flags &= ~2; int nXSprite = pSprite->extra; pSprite->z -= 4 << 8; - int nSurface = tileGetSurfType(actor->hit().florhit); + int nSurface = tileGetSurfType(actor->hit().florhit.legacyVal); switch (pSprite->type) { case kThingDripWater: @@ -7369,20 +7370,52 @@ void MakeSplash(DBloodActor* actor) // //--------------------------------------------------------------------------- -FSerializer& Serialize(FSerializer& arc, const char* keyname, SPRITEHIT& w, SPRITEHIT* def) +FSerializer& Serialize(FSerializer& arc, const char* keyname, Collision& w, Collision* def) { int empty = 0; if (arc.isReading()) w = {}; if (arc.BeginObject(keyname)) { - arc("hit", w.hit, &empty) - ("ceilhit", w.ceilhit, &empty) - ("florhit", w.florhit, &empty) + arc("type", w.type, &empty) + ("index", w.index, &empty) + ("legacyval", w.legacyVal, &empty) + ("actor", w.actor) .EndObject(); } return arc; } +FSerializer& Serialize(FSerializer& arc, const char* keyname, SPRITEHIT& w, SPRITEHIT* def) +{ +#ifdef OLD_SAVEGAME + int empty = 0; + int hit = w.hit.legacyVal, ceilhit = w.ceilhit.legacyVal, florhit = w.florhit.legacyVal; + if (arc.isReading()) w = {}; + if (arc.BeginObject(keyname)) + { + arc("hit", hit, &empty) + ("ceilhit", ceilhit, &empty) + ("florhit", florhit, &empty) + .EndObject(); + if (arc.isReading()) + { + w.hit.setFromEngine(hit); + w.florhit.setFromEngine(florhit); + w.ceilhit.setFromEngine(ceilhit); + } + } +#else + if (arc.BeginObject(keyname)) + { + arc("hit", w.hit) + ("ceilhit", w.ceilhit) + ("florhit", w.florhit) + .EndObject(); + } +#endif + return arc; +} + void SerializeActor(FSerializer& arc) { if (arc.BeginObject("actor")) diff --git a/source/games/blood/src/aiunicult.cpp b/source/games/blood/src/aiunicult.cpp index 94e9dc39c..252aadea4 100644 --- a/source/games/blood/src/aiunicult.cpp +++ b/source/games/blood/src/aiunicult.cpp @@ -938,7 +938,7 @@ static void unicultThinkChase(DBloodActor* actor) else pXSprite->dodgeDir = -1; } - if (((gSpriteHit[pSprite->extra].hit & 0xc000) == 0x8000) || ((gSpriteHit[pSprite->extra].hit & 0xc000) == 0xc000)) + if (gSpriteHit[pSprite->extra].hit.type == kHitWall || gSpriteHit[pSprite->extra].hit.type == kHitSprite) { if (spriteIsUnderwater(actor)) aiGenDudeNewState(actor, &genDudeChaseW); else aiGenDudeNewState(actor, &genDudeChaseL); diff --git a/source/games/blood/src/animatesprite.cpp b/source/games/blood/src/animatesprite.cpp index 812376d9e..7eb1d64e5 100644 --- a/source/games/blood/src/animatesprite.cpp +++ b/source/games/blood/src/animatesprite.cpp @@ -601,7 +601,7 @@ void viewProcessSprites(spritetype* tsprite, int& spritesortcnt, int32_t cX, int { if (nXSprite > 0) { - if (gSpriteHit[nXSprite].florhit == 0) + if (gSpriteHit[nXSprite].florhit.type == kHitNone) nAnim = 1; } else @@ -927,7 +927,8 @@ void viewProcessSprites(spritetype* tsprite, int& spritesortcnt, int32_t cX, int case kStatThing: { viewApplyDefaultPal(pTSprite, pSector); - if (pTSprite->type < kThingBase || pTSprite->type >= kThingMax || !gSpriteHit[nXSprite].florhit) { + if (pTSprite->type < kThingBase || pTSprite->type >= kThingMax || gSpriteHit[nXSprite].florhit.type == kHitNone) + { if ((pTSprite->flags & kPhysMove) && getflorzofslope(pTSprite->sectnum, pTSprite->x, pTSprite->y) >= cZ) viewAddEffect(tsprite, spritesortcnt, nTSprite, kViewEffectShadow); } diff --git a/source/games/blood/src/bloodactor.h b/source/games/blood/src/bloodactor.h index 1e697afe5..1c73a421b 100644 --- a/source/games/blood/src/bloodactor.h +++ b/source/games/blood/src/bloodactor.h @@ -2,6 +2,87 @@ BEGIN_BLD_NS +class DBloodActor; + +// Wrapper around the insane collision info mess from Build. +struct Collision +{ + int type; + int index; + int legacyVal; // should be removed later, but needed for converting back for unadjusted code. + DBloodActor* actor; + + Collision() = default; + Collision(int legacyval) { setFromEngine(legacyval); } + + // need forward declarations of these. + int actorIndex(DBloodActor*); + DBloodActor* Actor(int); + + int setNone() + { + type = kHitNone; + index = -1; + legacyVal = 0; + actor = nullptr; + return kHitNone; + } + + int setSector(int num) + { + type = kHitSector; + index = num; + legacyVal = type | index; + actor = nullptr; + return kHitSector; + } + int setWall(int num) + { + type = kHitWall; + index = num; + legacyVal = type | index; + actor = nullptr; + return kHitWall; + } + int setSprite(DBloodActor* num) + { + type = kHitSprite; + index = -1; + legacyVal = type | actorIndex(num); + actor = num; + return kHitSprite; + } + + int setFromEngine(int value) + { + legacyVal = value; + type = value & kHitTypeMask; + if (type == 0) { index = -1; actor = nullptr; } + else if (type != kHitSprite) { index = value & kHitIndexMask; actor = nullptr; } + else { index = -1; actor = Actor(value & kHitIndexMask); } + return type; + } + + walltype* wall() + { + assert(type == kHitWall); + return &::wall[index]; + } + + sectortype* sector() + { + assert(type == kHitSector); + return &::sector[index]; + } + +}; + +struct SPRITEHIT +{ + Collision hit, ceilhit, florhit; +}; +extern SPRITEHIT gSpriteHit[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. @@ -224,75 +305,6 @@ inline DBloodActor* PLAYER::actor() } -// Wrapper around the insane collision info mess from Build. -struct Collision -{ - int type; - int index; - int legacyVal; // should be removed later, but needed for converting back for unadjusted code. - DBloodActor* actor; - - Collision() = default; - Collision(int legacyval) { setFromEngine(legacyval); } - - int setNone() - { - type = kHitNone; - index = -1; - legacyVal = 0; - actor = nullptr; - return kHitNone; - } - - int setSector(int num) - { - type = kHitSector; - index = num; - legacyVal = type | index; - actor = nullptr; - return kHitSector; - } - int setWall(int num) - { - type = kHitWall; - index = num; - legacyVal = type | index; - actor = nullptr; - return kHitWall; - } - int setSprite(DBloodActor* num) - { - type = kHitSprite; - index = -1; - legacyVal = type | int(num - bloodActors); - actor = num; - return kHitSprite; - } - - int setFromEngine(int value) - { - legacyVal = value; - type = value & kHitTypeMask; - if (type == 0) { index = -1; actor = nullptr; } - else if (type != kHitSprite) { index = value & kHitIndexMask; actor = nullptr; } - else { index = -1; actor = &bloodActors[value & kHitIndexMask]; } - return type; - } - - walltype* wall() - { - assert(type == kHitWall); - return &::wall[index]; - } - - sectortype* sector() - { - assert(type == kHitSector); - return &::sector[index]; - } - -}; - inline DBloodActor* getUpperLink(int sect) { auto l = gUpperLink[sect]; @@ -305,11 +317,6 @@ inline DBloodActor* getLowerLink(int sect) return l == -1 ? nullptr : &bloodActors[l]; } -inline void viewBackupSpriteLoc(DBloodActor* actor) -{ - viewBackupSpriteLoc(actor->s().index, &actor->s()); -} - inline FSerializer& Serialize(FSerializer& arc, const char* keyname, DBloodActor*& w, DBloodActor** def) { int index = w? int(w - bloodActors) : -1; @@ -331,13 +338,24 @@ inline void sfxKill3DSound(DBloodActor* pSprite, int a2 = -1, int a3 = -1) sfxKill3DSound(&pSprite->s(), a2, a3); } -void ChangeActorStat(DBloodActor* actor, int stat) +inline void ChangeActorStat(DBloodActor* actor, int stat) { ChangeSpriteStat(actor->s().index, stat); } -void ChangeActorSect(DBloodActor* actor, int stat) +inline void ChangeActorSect(DBloodActor* actor, int stat) { ChangeSpriteSect(actor->s().index, stat); } + +inline int Collision::actorIndex(DBloodActor* actor) +{ + return int(actor - bloodActors); +} + +inline DBloodActor* Collision::Actor(int a) +{ + return &bloodActors[a]; +} + END_BLD_NS diff --git a/source/games/blood/src/callback.cpp b/source/games/blood/src/callback.cpp index 86db15d58..a6d804932 100644 --- a/source/games/blood/src/callback.cpp +++ b/source/games/blood/src/callback.cpp @@ -394,8 +394,9 @@ void fxBloodBits(DBloodActor* actor, int) // 14 { if (!actor) return; spritetype *pSprite = &actor->s(); - int ceilZ, ceilHit, floorZ, floorHit; - GetZRange(pSprite, &ceilZ, &ceilHit, &floorZ, &floorHit, pSprite->clipdist, CLIPMASK0); + int ceilZ, floorZ; + Collision floorColl, ceilColl; + GetZRange(pSprite, &ceilZ, &ceilColl, &floorZ, &floorColl, pSprite->clipdist, CLIPMASK0); int top, bottom; GetSpriteExtents(pSprite, &top, &bottom); pSprite->z += floorZ-bottom; @@ -441,8 +442,11 @@ int sawedOffSleeveSnd[] = { 610, 612 }; void fxBouncingSleeve(DBloodActor* actor, int) // 16 { if (!actor) return; - spritetype* pSprite = &actor->s(); int ceilZ, ceilHit, floorZ, floorHit; - GetZRange(pSprite, &ceilZ, &ceilHit, &floorZ, &floorHit, pSprite->clipdist, CLIPMASK0); + spritetype* pSprite = &actor->s(); + int ceilZ, floorZ; + Collision floorColl, ceilColl; + + GetZRange(pSprite, &ceilZ, &ceilColl, &floorZ, &floorColl, pSprite->clipdist, CLIPMASK0); int top, bottom; GetSpriteExtents(pSprite, &top, &bottom); pSprite->z += floorZ - bottom; @@ -550,8 +554,10 @@ void fxPodBloodSplat(DBloodActor* actor, int) // 19 { if (!actor) return; spritetype *pSprite = &actor->s(); - int ceilZ, ceilHit, floorZ, floorHit; - GetZRange(pSprite, &ceilZ, &ceilHit, &floorZ, &floorHit, pSprite->clipdist, CLIPMASK0); + int ceilZ, floorZ; + Collision floorColl, ceilColl; + + GetZRange(pSprite, &ceilZ, &ceilColl, &floorZ, &floorColl, pSprite->clipdist, CLIPMASK0); int top, bottom; GetSpriteExtents(pSprite, &top, &bottom); pSprite->z += floorZ-bottom; diff --git a/source/games/blood/src/db.h b/source/games/blood/src/db.h index dc1031eb1..a51047bc2 100644 --- a/source/games/blood/src/db.h +++ b/source/games/blood/src/db.h @@ -289,11 +289,6 @@ struct MAPHEADER2 { char pad[52]; }; -struct SPRITEHIT -{ - int hit, ceilhit, florhit; -}; - #pragma pack(pop) extern unsigned short gStatCount[kMaxStatus + 1];; @@ -307,7 +302,6 @@ extern XWALL xwall[kMaxXWalls]; extern FixedBitArray activeXSprites; -extern SPRITEHIT gSpriteHit[kMaxXSprites]; extern char qsector_filler[kMaxSectors]; diff --git a/source/games/blood/src/gameutil.cpp b/source/games/blood/src/gameutil.cpp index 334fa9c22..c52beecdb 100644 --- a/source/games/blood/src/gameutil.cpp +++ b/source/games/blood/src/gameutil.cpp @@ -617,16 +617,19 @@ int VectorScan(spritetype *pSprite, int nOffset, int nZOffset, int dx, int dy, i return -1; } -void GetZRange(spritetype *pSprite, int *ceilZ, int *ceilHit, int *floorZ, int *floorHit, int nDist, unsigned int nMask, unsigned int nClipParallax) +void GetZRange(spritetype *pSprite, int *ceilZ, Collision *ceilColl, int *floorZ, Collision *floorColl, int nDist, unsigned int nMask, unsigned int nClipParallax) { + int floorHit, ceilHit; assert(pSprite != NULL); int bakCstat = pSprite->cstat; int32_t nTemp1, nTemp2; pSprite->cstat &= ~257; - getzrange(&pSprite->pos, pSprite->sectnum, (int32_t*)ceilZ, (int32_t*)ceilHit, (int32_t*)floorZ, (int32_t*)floorHit, nDist, nMask); - if (((*floorHit) & 0xc000) == 0x4000) + getzrange(&pSprite->pos, pSprite->sectnum, (int32_t*)ceilZ, &ceilHit, (int32_t*)floorZ, &floorHit, nDist, nMask); + ceilColl->setFromEngine(ceilHit); + floorColl->setFromEngine(floorHit); + if (floorColl->type == kHitSector) { - int nSector = (*floorHit) & 0x3fff; + int nSector = floorColl->index; if ((nClipParallax & PARALLAXCLIP_FLOOR) == 0 && (sector[nSector].floorstat & 1)) *floorZ = 0x7fffffff; if (sector[nSector].extra > 0) @@ -640,13 +643,14 @@ void GetZRange(spritetype *pSprite, int *ceilZ, int *ceilHit, int *floorZ, int * int nLink = sprite[nSprite].owner & 0xfff; vec3_t lpos = { pSprite->x + sprite[nLink].x - sprite[nSprite].x, pSprite->y + sprite[nLink].y - sprite[nSprite].y, pSprite->z + sprite[nLink].z - sprite[nSprite].z }; - getzrange(&lpos, sprite[nLink].sectnum, &nTemp1, &nTemp2, (int32_t*)floorZ, (int32_t*)floorHit, nDist, nMask); + getzrange(&lpos, sprite[nLink].sectnum, &nTemp1, &nTemp2, (int32_t*)floorZ, &floorHit, nDist, nMask); *floorZ -= sprite[nLink].z - sprite[nSprite].z; + floorColl->setFromEngine(floorHit); } } - if (((*ceilHit) & 0xc000) == 0x4000) + if (ceilColl->type == kHitSector) { - int nSector = (*ceilHit) & 0x3fff; + int nSector = ceilColl->index; if ((nClipParallax & PARALLAXCLIP_CEILING) == 0 && (sector[nSector].ceilingstat & 1)) *ceilZ = 0x80000000; if (gLowerLink[nSector] >= 0) @@ -655,22 +659,25 @@ void GetZRange(spritetype *pSprite, int *ceilZ, int *ceilHit, int *floorZ, int * int nLink = sprite[nSprite].owner & 0xfff; vec3_t lpos = { pSprite->x + sprite[nLink].x - sprite[nSprite].x, pSprite->y + sprite[nLink].y - sprite[nSprite].y, pSprite->z + sprite[nLink].z - sprite[nSprite].z }; - getzrange(&lpos, sprite[nLink].sectnum, (int32_t*)ceilZ, (int32_t*)ceilHit, &nTemp1, &nTemp2, - nDist, nMask); + getzrange(&lpos, sprite[nLink].sectnum, (int32_t*)ceilZ, &ceilHit, &nTemp1, &nTemp2, nDist, nMask); *ceilZ -= sprite[nLink].z - sprite[nSprite].z; + ceilColl->setFromEngine(ceilHit); } } pSprite->cstat = bakCstat; } -void GetZRangeAtXYZ(int x, int y, int z, int nSector, int *ceilZ, int *ceilHit, int *floorZ, int *floorHit, int nDist, unsigned int nMask, unsigned int nClipParallax) +void GetZRangeAtXYZ(int x, int y, int z, int nSector, int *ceilZ, Collision* ceilColl, int* floorZ, Collision* floorColl, int nDist, unsigned int nMask, unsigned int nClipParallax) { + int ceilHit, floorHit; int32_t nTemp1, nTemp2; vec3_t lpos = { x, y, z }; - getzrange(&lpos, nSector, (int32_t*)ceilZ, (int32_t*)ceilHit, (int32_t*)floorZ, (int32_t*)floorHit, nDist, nMask); - if (((*floorHit) & 0xc000) == 0x4000) + getzrange(&lpos, nSector, (int32_t*)ceilZ, &ceilHit, (int32_t*)floorZ, &floorHit, nDist, nMask); + ceilColl->setFromEngine(ceilHit); + floorColl->setFromEngine(floorHit); + if (floorColl->type == kHitSector) { - int nSector = (*floorHit) & 0x3fff; + int nSector = floorColl->index; if ((nClipParallax & PARALLAXCLIP_FLOOR) == 0 && (sector[nSector].floorstat & 1)) *floorZ = 0x7fffffff; if (sector[nSector].extra > 0) @@ -684,13 +691,13 @@ void GetZRangeAtXYZ(int x, int y, int z, int nSector, int *ceilZ, int *ceilHit, int nLink = sprite[nSprite].owner & 0xfff; lpos = { x + sprite[nLink].x - sprite[nSprite].x, y + sprite[nLink].y - sprite[nSprite].y, z + sprite[nLink].z - sprite[nSprite].z }; - getzrange(&lpos, sprite[nLink].sectnum, &nTemp1, &nTemp2, (int32_t*)floorZ, (int32_t*)floorHit, nDist, nMask); + getzrange(&lpos, sprite[nLink].sectnum, &nTemp1, &nTemp2, (int32_t*)floorZ, &floorHit, nDist, nMask); *floorZ -= sprite[nLink].z - sprite[nSprite].z; } } - if (((*ceilHit) & 0xc000) == 0x4000) + if (ceilColl->type == kHitSector) { - int nSector = (*ceilHit) & 0x3fff; + int nSector = ceilColl->index; if ((nClipParallax & PARALLAXCLIP_CEILING) == 0 && (sector[nSector].ceilingstat & 1)) *ceilZ = 0x80000000; if (gLowerLink[nSector] >= 0) @@ -699,7 +706,7 @@ void GetZRangeAtXYZ(int x, int y, int z, int nSector, int *ceilZ, int *ceilHit, int nLink = sprite[nSprite].owner & 0xfff; lpos = { x + sprite[nLink].x - sprite[nSprite].x, y + sprite[nLink].y - sprite[nSprite].y, z + sprite[nLink].z - sprite[nSprite].z }; - getzrange(&lpos, sprite[nLink].sectnum, (int32_t*)ceilZ, (int32_t*)ceilHit, &nTemp1, &nTemp2, nDist, nMask); + getzrange(&lpos, sprite[nLink].sectnum, (int32_t*)ceilZ, &ceilHit, &nTemp1, &nTemp2, nDist, nMask); *ceilZ -= sprite[nLink].z - sprite[nSprite].z; } } diff --git a/source/games/blood/src/gameutil.h b/source/games/blood/src/gameutil.h index e1a220e20..39eb7b041 100644 --- a/source/games/blood/src/gameutil.h +++ b/source/games/blood/src/gameutil.h @@ -73,7 +73,7 @@ inline bool wallRangeIsFine(int nIndex) { return (nIndex >= 0 && nIndex < kMaxWalls); } /// - +struct Collision; bool AreSectorsNeighbors(int sect1, int sect2); bool FindSector(int nX, int nY, int nZ, int *nSector); bool FindSector(int nX, int nY, int *nSector); @@ -86,8 +86,8 @@ void GetWallNormal(int nWall, int *pX, int *pY); bool IntersectRay(int wx, int wy, int wdx, int wdy, int x1, int y1, int z1, int x2, int y2, int z2, int *ix, int *iy, int *iz); int HitScan(spritetype *pSprite, int z, int dx, int dy, int dz, unsigned int nMask, int a8); int VectorScan(spritetype *pSprite, int nOffset, int nZOffset, int dx, int dy, int dz, int nRange, int ac); -void GetZRange(spritetype *pSprite, int *ceilZ, int *ceilHit, int *floorZ, int *floorHit, int nDist, unsigned int nMask, unsigned int nClipParallax = 0); -void GetZRangeAtXYZ(int x, int y, int z, int nSector, int *ceilZ, int *ceilHit, int *floorZ, int *floorHit, int nDist, unsigned int nMask, unsigned int nClipParallax = 0); +void GetZRange(spritetype *pSprite, int *ceilZ, Collision *ceilHit, int *floorZ, Collision *floorHit, int nDist, unsigned int nMask, unsigned int nClipParallax = 0); +void GetZRangeAtXYZ(int x, int y, int z, int nSector, int *ceilZ, Collision *ceilHit, int *floorZ, Collision *floorHit, int nDist, unsigned int nMask, unsigned int nClipParallax = 0); int GetDistToLine(int x1, int y1, int x2, int y2, int x3, int y3); unsigned int ClipMove(vec3_t* pos, int *nSector, int xv, int yv, int wd, int cd, int fd, unsigned int nMask, int tracecount = 3); int GetClosestSectors(int nSector, int x, int y, int nDist, short *pSectors, char *pSectBit); diff --git a/source/games/blood/src/nnexts.cpp b/source/games/blood/src/nnexts.cpp index dc2ff4357..32ff9869d 100644 --- a/source/games/blood/src/nnexts.cpp +++ b/source/games/blood/src/nnexts.cpp @@ -1420,7 +1420,7 @@ void nnExtProcessSuperSprites() { pPlayer = &gPlayer[a]; auto pact = pPlayer->actor(); - if ((pact->hit().hit & 0xc000) == 0xc000 && (pact->hit().hit & 0x3fff) == nDebris) + if (pact->hit().hit.type == kHitSprite && pact->hit().hit.index == nDebris) { int nSpeed = approxDist(pact->xvel(), pact->yvel()); nSpeed = ClipLow(nSpeed - MulScale(nSpeed, mass, 6), 0x9000 - (mass << 3)); @@ -1723,7 +1723,8 @@ void debrisMove(int listIndex) int top, bottom, i; GetActorExtents(actor, &top, &bottom); - int moveHit = 0; + Collision moveHit; + moveHit.setNone(); int floorDist = (bottom - pSprite->z) >> 2; int ceilDist = (pSprite->z - top) >> 2; int clipDist = pSprite->clipdist << 2; @@ -1758,8 +1759,10 @@ void debrisMove(int listIndex) nSector = nSector2; } - if ((gSpriteHit[nXSprite].hit & 0xc000) == 0x8000) { - i = moveHit = gSpriteHit[nXSprite].hit & 0x3fff; + if (gSpriteHit[nXSprite].hit.type == kHitWall) + { + moveHit = gSpriteHit[nXSprite].hit; + i = moveHit.index; actWallBounceVector((int*)&xvel[nSprite], (int*)&yvel[nSprite], i, tmpFraction); } @@ -1779,8 +1782,9 @@ void debrisMove(int listIndex) if (zvel[nSprite]) pSprite->z += zvel[nSprite] >> 8; - int ceilZ, ceilHit, floorZ, floorHit; - GetZRange(pSprite, &ceilZ, &ceilHit, &floorZ, &floorHit, clipDist, CLIPMASK0, PARALLAXCLIP_CEILING | PARALLAXCLIP_FLOOR); + int ceilZ, floorZ; + Collision ceilColl, floorColl; + GetZRange(pSprite, &ceilZ, &ceilColl, &floorZ, &floorColl, clipDist, CLIPMASK0, PARALLAXCLIP_CEILING | PARALLAXCLIP_FLOOR); GetSpriteExtents(pSprite, &top, &bottom); if ((pXSprite->physAttr & kPhysDebrisSwim) && uwater) { @@ -1810,7 +1814,7 @@ void debrisMove(int listIndex) } if ((i = CheckLink(pSprite)) != 0) { - GetZRange(pSprite, &ceilZ, &ceilHit, &floorZ, &floorHit, clipDist, CLIPMASK0, PARALLAXCLIP_CEILING | PARALLAXCLIP_FLOOR); + GetZRange(pSprite, &ceilZ, &ceilColl, &floorZ, &floorColl, clipDist, CLIPMASK0, PARALLAXCLIP_CEILING | PARALLAXCLIP_FLOOR); if (!(pSprite->cstat & CSTAT_SPRITE_INVISIBLE)) { switch (i) { case kMarkerUpWater: @@ -1835,7 +1839,7 @@ void debrisMove(int listIndex) if (floorZ <= bottom) { - gSpriteHit[nXSprite].florhit = floorHit; + gSpriteHit[nXSprite].florhit = floorColl; int v30 = zvel[nSprite] - velFloor[pSprite->sectnum]; if (v30 > 0) { @@ -1849,9 +1853,9 @@ void debrisMove(int listIndex) pXSprite->physAttr &= ~kPhysFalling; } - moveHit = floorHit; + moveHit = floorColl; DBloodActor* pFX = NULL, *pFX2 = NULL; - switch (tileGetSurfType(floorHit)) { + switch (tileGetSurfType(floorColl.legacyVal)) { case kSurfLava: if ((pFX = gFX.fxSpawnActor(FX_10, pSprite->sectnum, pSprite->x, pSprite->y, floorZ, 0)) == NULL) break; for (i = 0; i < 7; i++) { @@ -1882,7 +1886,7 @@ void debrisMove(int listIndex) if (top <= ceilZ) { - gSpriteHit[nXSprite].ceilhit = moveHit = ceilHit; + gSpriteHit[nXSprite].ceilhit = moveHit = ceilColl; pSprite->z += ClipLow(ceilZ - top, 0); if (zvel[nSprite] <= 0 && (pXSprite->physAttr & kPhysFalling)) zvel[nSprite] = MulScale(-zvel[nSprite], 0x2000, 16); @@ -1894,7 +1898,7 @@ void debrisMove(int listIndex) } - if (moveHit && pXSprite->Impact && !pXSprite->locked && !pXSprite->isTriggered && (pXSprite->state == pXSprite->restState || pXSprite->Interrutable)) { + if (moveHit.type != kHitNone && pXSprite->Impact && !pXSprite->locked && !pXSprite->isTriggered && (pXSprite->state == pXSprite->restState || pXSprite->Interrutable)) { if (pSprite->type >= kThingBase && pSprite->type < kThingMax) changespritestat(nSprite, kStatThing); @@ -1903,12 +1907,13 @@ void debrisMove(int listIndex) } if (!xvel[nSprite] && !yvel[nSprite]) return; - else if ((floorHit & 0xc000) == 0xc000) { + else if (floorColl.type == kHitSprite) + { - int nHitSprite = floorHit & 0x3fff; - if ((sprite[nHitSprite].cstat & 0x30) == 0) { - xvel[nSprite] += MulScale(4, pSprite->x - sprite[nHitSprite].x, 2); - yvel[nSprite] += MulScale(4, pSprite->y - sprite[nHitSprite].y, 2); + if ((floorColl.actor->s().cstat & 0x30) == 0) + { + xvel[nSprite] += MulScale(4, pSprite->x - floorColl.actor->s().x, 2); + yvel[nSprite] += MulScale(4, pSprite->y - floorColl.actor->s().y, 2); return; } } @@ -3128,22 +3133,29 @@ void useSpriteDamager(XSPRITE* pXSource, int objType, int objIndex) { damageSprites(pXSource, &sprite[objIndex]); break; case OBJ_SECTOR: + { GetSpriteExtents(pSource, &top, &bottom); - floor = (bottom >= pSector->floorz); ceil = (top <= pSector->ceilingz); - wall = (pSource->cstat & 0x10); enter = (!floor && !ceil && !wall); - for (i = headspritesect[objIndex]; i != -1; i = nextspritesect[i]) { + floor = (bottom >= pSector->floorz); + ceil = (top <= pSector->ceilingz); + wall = (pSource->cstat & 0x10); + enter = (!floor && !ceil && !wall); + for (i = headspritesect[objIndex]; i != -1; i = nextspritesect[i]) + { + auto& hit = gSpriteHit[sprite[i].extra]; + if (!IsDudeSprite(&sprite[i]) || !xspriRangeIsFine(sprite[i].extra)) continue; else if (enter) damageSprites(pXSource, &sprite[i]); - else if (floor && (gSpriteHit[sprite[i].extra].florhit & 0xc000) == 0x4000 && (gSpriteHit[sprite[i].extra].florhit & 0x3fff) == objIndex) + else if (floor && hit.florhit.type == kHitSector && hit.florhit.index == objIndex) damageSprites(pXSource, &sprite[i]); - else if (ceil && (gSpriteHit[sprite[i].extra].ceilhit & 0xc000) == 0x4000 && (gSpriteHit[sprite[i].extra].ceilhit & 0x3fff) == objIndex) + else if (ceil && hit.ceilhit.type == kHitSector && hit.ceilhit.index == objIndex) damageSprites(pXSource, &sprite[i]); - else if (wall && (gSpriteHit[sprite[i].extra].hit & 0xc000) == 0x8000 && sectorofwall(gSpriteHit[sprite[i].extra].hit & 0x3fff) == objIndex) + else if (wall && hit.hit.type == kHitWall && sectorofwall(hit.hit.index) == objIndex) damageSprites(pXSource, &sprite[i]); } break; + } case -1: for (i = headspritestat[kStatDude]; i != -1; i = nextspritestat[i]) { if (sprite[i].statnum != kStatDude) continue; @@ -4190,54 +4202,63 @@ bool condCheckSprite(XSPRITE* pXCond, int cmpOp, bool PUSH) { else if (pSpr->type >= kThingBase && pSpr->type < kThingMax) var = thingInfo[pSpr->type - kThingBase].startHealth << 4; return condCmp((kPercFull * pXSpr->health) / ClipLow(var, 1), arg1, arg2, cmpOp); case 55: // touching ceil of sector? - if ((gSpriteHit[pSpr->extra].ceilhit & 0xc000) != 0x4000) return false; - else if (PUSH) condPush(pXCond, OBJ_SECTOR, gSpriteHit[pSpr->extra].ceilhit & 0x3fff); + if (gSpriteHit[pSpr->extra].ceilhit.type != kHitSector) return false; + else if (PUSH) condPush(pXCond, OBJ_SECTOR, gSpriteHit[pSpr->extra].ceilhit.index); return true; case 56: // touching floor of sector? - if ((gSpriteHit[pSpr->extra].florhit & 0xc000) != 0x4000) return false; - else if (PUSH) condPush(pXCond, OBJ_SECTOR, gSpriteHit[pSpr->extra].florhit & 0x3fff); + if (gSpriteHit[pSpr->extra].florhit.type != kHitSector) return false; + else if (PUSH) condPush(pXCond, OBJ_SECTOR, gSpriteHit[pSpr->extra].florhit.index); return true; case 57: // touching walls of sector? - if ((gSpriteHit[pSpr->extra].hit & 0xc000) != 0x8000) return false; - else if (PUSH) condPush(pXCond, OBJ_WALL, gSpriteHit[pSpr->extra].hit & 0x3fff); + if (gSpriteHit[pSpr->extra].hit.type != kHitWall) return false; + else if (PUSH) condPush(pXCond, OBJ_WALL, gSpriteHit[pSpr->extra].hit.index); return true; case 58: // touching another sprite? + { + DBloodActor* actorvar = nullptr; switch (arg3) { case 0: case 1: - if ((gSpriteHit[pSpr->extra].florhit & 0xc000) == 0xc000) var = gSpriteHit[pSpr->extra].florhit & 0x3fff; + if (gSpriteHit[pSpr->extra].florhit.type == kHitSprite) actorvar = gSpriteHit[pSpr->extra].florhit.actor; if (arg3 || var >= 0) break; fallthrough__; case 2: - if ((gSpriteHit[pSpr->extra].hit & 0xc000) == 0xc000) var = gSpriteHit[pSpr->extra].hit & 0x3fff; + if (gSpriteHit[pSpr->extra].hit.type == kHitSprite) actorvar = gSpriteHit[pSpr->extra].hit.actor; if (arg3 || var >= 0) break; fallthrough__; case 3: - if ((gSpriteHit[pSpr->extra].ceilhit & 0xc000) == 0xc000) var = gSpriteHit[pSpr->extra].ceilhit & 0x3fff; + if (gSpriteHit[pSpr->extra].ceilhit.type == kHitSprite) actorvar = gSpriteHit[pSpr->extra].ceilhit.actor; break; } - if (var < 0) { // check if something touching this sprite - for (int i = kMaxXSprites - 1, idx = i; i > 0; idx = xsprite[--i].reference) { + if (actorvar == nullptr) + { + // check if something touching this sprite + for (int i = kMaxXSprites - 1, idx = i; i > 0; idx = xsprite[--i].reference) + { if (idx < 0 || (sprite[idx].flags & kHitagRespawn)) continue; + auto iactor = &bloodActors[idx]; + auto objactor = &bloodActors[objIndex]; + auto& hit = gSpriteHit[i]; switch (arg3) { case 0: case 1: - if ((gSpriteHit[i].ceilhit & 0xc000) == 0xc000 && (gSpriteHit[i].ceilhit & 0x3fff) == objIndex) var = idx; - if (arg3 || var >= 0) break; + if (hit.ceilhit.type == kHitSprite && hit.ceilhit.actor == objactor) actorvar = iactor; + if (arg3 || actorvar) break; fallthrough__; case 2: - if ((gSpriteHit[i].hit & 0xc000) == 0xc000 && (gSpriteHit[i].hit & 0x3fff) == objIndex) var = idx; - if (arg3 || var >= 0) break; + if (hit.hit.type == kHitSprite && hit.hit.actor == objactor) actorvar = iactor; + if (arg3 || actorvar) break; fallthrough__; case 3: - if ((gSpriteHit[i].florhit & 0xc000) == 0xc000 && (gSpriteHit[i].florhit & 0x3fff) == objIndex) var = idx; + if (hit.florhit.type == kHitSprite && hit.florhit.actor == objactor) actorvar = iactor; break; } } } - if (var < 0) return false; - else if (PUSH) condPush(pXCond, OBJ_SPRITE, var); + if (actorvar == nullptr) return false; + else if (PUSH) condPush(pXCond, OBJ_SPRITE, actorvar->s().index); return true; + } case 65: // compare burn time (in %) var = (IsDudeSprite(pSpr)) ? 2400 : 1200; if (!condCmp((kPercFull * pXSpr->burnTime) / var, arg1, arg2, cmpOp)) return false; @@ -7129,21 +7150,20 @@ void aiPatrolMove(DBloodActor* actor) { if (abs(nAng) > goalAng || ((pXTarget->waitTime > 0 || pXTarget->data1 == pXTarget->data2) && aiPatrolMarkerReached(pSprite, pXSprite))) { - xvel[pSprite->index] = 0; - yvel[pSprite->index] = 0; + actor->xvel() = 0; + actor->yvel() = 0; return; } - if ((gSpriteHit[pSprite->extra].hit & 0xc000) == 0xc000) { - - int nHSprite = gSpriteHit[pSprite->extra].hit & 0x3fff; - XSPRITE* pXSprite2 = &xsprite[sprite[nHSprite].extra]; + if (gSpriteHit[pSprite->extra].hit.type == kHitSprite) + { + auto hitactor = gSpriteHit[pSprite->extra].hit.actor; - pXSprite2->dodgeDir = -1; + hitactor->x().dodgeDir = -1; pXSprite->dodgeDir = 1; - aiMoveDodge(&bloodActors[pXSprite->reference]); + aiMoveDodge(hitactor); } else { @@ -7273,11 +7293,12 @@ bool spritesTouching(int nXSprite1, int nXSprite2) { if (!xspriRangeIsFine(nXSprite1) || !xspriRangeIsFine(nXSprite2)) return false; - int nHSprite = -1; - if ((gSpriteHit[nXSprite1].hit & 0xc000) == 0xc000) nHSprite = gSpriteHit[nXSprite1].hit & 0x3fff; - else if ((gSpriteHit[nXSprite1].florhit & 0xc000) == 0xc000) nHSprite = gSpriteHit[nXSprite1].florhit & 0x3fff; - else if ((gSpriteHit[nXSprite1].ceilhit & 0xc000) == 0xc000) nHSprite = gSpriteHit[nXSprite1].ceilhit & 0x3fff; - return (spriRangeIsFine(nHSprite) && sprite[nHSprite].extra == nXSprite2); + DBloodActor* hitactor = nullptr; + if (gSpriteHit[nXSprite1].hit.type == kHitSprite) hitactor = gSpriteHit[nXSprite1].hit.actor; + else if (gSpriteHit[nXSprite1].florhit.type == kHitSprite) hitactor = gSpriteHit[nXSprite1].florhit.actor; + else if (gSpriteHit[nXSprite1].ceilhit.type == kHitSprite) hitactor = gSpriteHit[nXSprite1].ceilhit.actor; + else return false; + return hitactor->hasX() && hitactor->s().extra == nXSprite2; } bool aiCanCrouch(spritetype* pSprite) { diff --git a/source/games/blood/src/player.cpp b/source/games/blood/src/player.cpp index 2b720052f..1ff871a02 100644 --- a/source/games/blood/src/player.cpp +++ b/source/games/blood/src/player.cpp @@ -1338,8 +1338,8 @@ void doslopetilting(PLAYER* pPlayer, double const scaleAdjust = 1) { auto* const pSprite = pPlayer->pSprite; auto* const pXSprite = pPlayer->pXSprite; - int const florhit = gSpriteHit[pSprite->extra].florhit & 0xc000; - char const va = pXSprite->height < 16 && (florhit == 0x4000 || florhit == 0) ? 1 : 0; + int const florhit = gSpriteHit[pSprite->extra].florhit.type; + char const va = pXSprite->height < 16 && (florhit == kHitSector || florhit == 0) ? 1 : 0; pPlayer->horizon.calcviewpitch(pSprite->pos.vec2, buildang(pSprite->ang), va, sector[pSprite->sectnum].floorstat & 2, pSprite->sectnum, scaleAdjust); } @@ -2151,11 +2151,11 @@ void playerLandingSound(PLAYER *pPlayer) }; spritetype *pSprite = pPlayer->pSprite; SPRITEHIT *pHit = &gSpriteHit[pSprite->extra]; - if (pHit->florhit) + if (pHit->florhit.type != kHitNone) { - if (!gGameOptions.bFriendlyFire && IsTargetTeammate(pPlayer, &sprite[pHit->florhit & 0x3fff])) + if (!gGameOptions.bFriendlyFire && pHit->florhit.type == kHitSprite && IsTargetTeammate(pPlayer, &pHit->florhit.actor->s())) return; - char nSurf = tileGetSurfType(pHit->florhit); + char nSurf = tileGetSurfType(pHit->florhit.legacyVal); if (nSurf) sfxPlay3DSound(pSprite, surfaceSound[nSurf], -1, 0); } diff --git a/source/games/blood/src/prediction.cpp b/source/games/blood/src/prediction.cpp index 20bc2ac77..7a8c9b376 100644 --- a/source/games/blood/src/prediction.cpp +++ b/source/games/blood/src/prediction.cpp @@ -232,9 +232,9 @@ static void fakeProcessInput(PLAYER *pPlayer, InputPacket *pInput) #endif int nSector = predict.sectnum; - int florhit = predict.at75.florhit & 0xc000; + int florhit = predict.at75.florhit.type; char va; - if (predict.floordist < 16 && (florhit == 0x4000 || florhit == 0)) + if (predict.floordist < 16 && (florhit == kHitSector || florhit == 0)) va = 1; else va = 0; @@ -399,11 +399,11 @@ static void fakeMoveDude(spritetype *pSprite) pSprite->cstat = bakCstat; } - switch (predict.at75.hit&0xc000) + switch (predict.at75.hit.type) { - case 0x8000: + case kHitSprite: { - int nHitWall = predict.at75.hit&0x3fff; + int nHitWall = predict.at75.hit.index; walltype *pHitWall = &wall[nHitWall]; if (pHitWall->nextsector != -1) { @@ -453,8 +453,9 @@ static void fakeMoveDude(spritetype *pSprite) pTempSprite->y = predict.y; pTempSprite->z = predict.z; pTempSprite->sectnum = predict.sectnum; - int ceilZ, ceilHit, floorZ, floorHit; - GetZRange(pTempSprite, &ceilZ, &ceilHit, &floorZ, &floorHit, wd, CLIPMASK0); + int ceilZ, floorZ; + Collision ceilColl, floorColl; + GetZRange(pTempSprite, &ceilZ, &ceilColl, &floorZ, &floorColl, wd, CLIPMASK0); GetSpriteExtents(pTempSprite, &top, &bottom); if (predict.at73 & 2) { @@ -493,17 +494,17 @@ static void fakeMoveDude(spritetype *pSprite) if (bottom >= floorZ) { int floorZ2 = floorZ; - int floorHit2 = floorHit; - GetZRange(pTempSprite, &ceilZ, &ceilHit, &floorZ, &floorHit, pSprite->clipdist<<2, CLIPMASK0, PARALLAXCLIP_CEILING|PARALLAXCLIP_FLOOR); + auto floorHit2 = floorColl; + GetZRange(pTempSprite, &ceilZ, &ceilColl, &floorZ, &floorColl, pSprite->clipdist<<2, CLIPMASK0, PARALLAXCLIP_CEILING|PARALLAXCLIP_FLOOR); if (bottom <= floorZ && predict.z-floorZ2 < bz) { floorZ = floorZ2; - floorHit = floorHit2; + floorColl = floorHit2; } } if (floorZ <= bottom) { - predict.at75.florhit = floorHit; + predict.at75.florhit = floorColl; predict.z += floorZ-bottom; int var44 = predict.zvel-velFloor[predict.sectnum]; if (var44 > 0) @@ -523,13 +524,13 @@ static void fakeMoveDude(spritetype *pSprite) } else { - predict.at75.florhit = 0; + predict.at75.florhit.setNone(); if (predict.at73 & 2) predict.at73 |= 4; } if (top <= ceilZ) { - predict.at75.ceilhit = ceilHit; + predict.at75.ceilhit = ceilColl; predict.z += ClipLow(ceilZ-top, 0); if (predict.zvel <= 0 && (predict.at73&4)) predict.zvel = MulScale(-predict.zvel, 0x2000, 16); @@ -542,13 +543,13 @@ static void fakeMoveDude(spritetype *pSprite) predict.floordist = ClipLow(floorZ-bottom, 0)>>8; if (predict.xvel || predict.yvel) { - if ((floorHit & 0xc000) == 0xc000) + if (floorColl.type == kHitSprite) { - int nHitSprite = floorHit & 0x3fff; - if ((sprite[nHitSprite].cstat & 0x30) == 0) + auto hitactor = floorColl.actor; + if ((hitactor->s().cstat & 0x30) == 0) { - predict.xvel += MulScale(4, predict.x - sprite[nHitSprite].x, 2); - predict.yvel += MulScale(4, predict.y - sprite[nHitSprite].y, 2); + predict.xvel += MulScale(4, predict.x - hitactor->s().x, 2); + predict.yvel += MulScale(4, predict.y - hitactor->s().y, 2); return; } } diff --git a/source/games/blood/src/view.cpp b/source/games/blood/src/view.cpp index 5847af9f8..2d109ca08 100644 --- a/source/games/blood/src/view.cpp +++ b/source/games/blood/src/view.cpp @@ -690,8 +690,9 @@ void viewDrawScreen(bool sceneonly) bDeliriumOld = bDelirium && gDeliriumBlur; int nClipDist = gView->pSprite->clipdist << 2; - int ve8, vec, vf0, vf4; - GetZRange(gView->pSprite, &vf4, &vf0, &vec, &ve8, nClipDist, 0); + int vec, vf4; + Collision c1, c2; + GetZRange(gView->pSprite, &vf4, &c1, &vec, &c2, nClipDist, 0); if (sceneonly) return; #if 0 int tmpSect = nSectnum; @@ -779,7 +780,8 @@ bool GameInterface::DrawAutomapPlayer(int x, int y, int z, int a, double const s if (i == gView->nPlayer || gGameOptions.nGameType == 1) { int nTile = pSprite->picnum; - int ceilZ, ceilHit, floorZ, floorHit; + int ceilZ, floorZ; + Collision ceilHit, floorHit; GetZRange(pSprite, &ceilZ, &ceilHit, &floorZ, &floorHit, (pSprite->clipdist << 2) + 16, CLIPMASK0, PARALLAXCLIP_CEILING | PARALLAXCLIP_FLOOR); int nTop, nBottom; GetSpriteExtents(pSprite, &nTop, &nBottom); diff --git a/source/games/blood/src/view.h b/source/games/blood/src/view.h index afaaa7dba..e0e52ad3b 100644 --- a/source/games/blood/src/view.h +++ b/source/games/blood/src/view.h @@ -28,6 +28,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "messages.h" #include "player.h" #include "interpolate.h" +#include "bloodactor.h" BEGIN_BLD_NS @@ -181,6 +182,10 @@ inline void viewBackupSpriteLoc(int nSprite, spritetype *pSprite) } } -void viewBackupSpriteLoc(DBloodActor* actor); +inline void viewBackupSpriteLoc(DBloodActor* actor) +{ + viewBackupSpriteLoc(actor->s().index, &actor->s()); +} + END_BLD_NS