- refactoring of all getzrange code to use the Collision struct.

This commit is contained in:
Christoph Oelckers 2021-09-02 20:23:51 +02:00
parent 55362edce4
commit 9221262dfc
13 changed files with 319 additions and 231 deletions

View file

@ -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"))

View file

@ -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);

View file

@ -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);
}

View file

@ -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

View file

@ -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;

View file

@ -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<MAXSPRITES> activeXSprites;
extern SPRITEHIT gSpriteHit[kMaxXSprites];
extern char qsector_filler[kMaxSectors];

View file

@ -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;
}
}

View file

@ -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);

View file

@ -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) {

View file

@ -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);
}

View file

@ -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;
}
}

View file

@ -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);

View file

@ -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