mirror of
https://github.com/ZDoom/Raze.git
synced 2025-03-13 20:42:11 +00:00
- refactoring of all getzrange code to use the Collision struct.
This commit is contained in:
parent
55362edce4
commit
9221262dfc
13 changed files with 319 additions and 231 deletions
|
@ -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"))
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue