- same procedure for Exhumed.

This commit is contained in:
Christoph Oelckers 2021-11-26 14:26:03 +01:00
parent 8ce34c7772
commit b3bbf8932e
19 changed files with 70 additions and 142 deletions

View file

@ -99,6 +99,7 @@ struct THitInfo : public HitInfoBase
struct CollisionBase
{
int type;
int exbits; // extended game-side info (only used by Exhumed)
union
{
// can only have one at a time

View file

@ -141,7 +141,8 @@ void AIAnubis::Tick(RunListEvent* ev)
int nFrame = SeqBase[nSeq] + ap->nFrame;
int nFlag = FrameFlag[nFrame];
Collision move(0);
Collision move;
move.setNone();
if (nAction > 0 && nAction < 11) {
move = MoveCreatureWithCaution(ap);
@ -185,7 +186,7 @@ void AIAnubis::Tick(RunListEvent* ev)
{
case kHitSprite:
{
if (move.actor == pTarget)
if (move.actor() == pTarget)
{
int nAng = getangle(pTarget->s().x - sp->x, pTarget->s().y - sp->y);
int nAngDiff = AngleDiff(sp->ang, nAng);

View file

@ -397,12 +397,12 @@ MOVEEND:
switch (coll.type)
{
case kHitWall:
pHitWall = coll.wall();
pHitWall = coll.hitWall;
goto HITWALL;
case 0xc000:
if (!coll.exbits)
{
hitactor = coll.actor;
hitactor = coll.actor();
goto HITSPRITE;
}
}

View file

@ -13,81 +13,6 @@ enum
kHitAux2 = 0x20000,
};
// Wrapper around the insane collision info mess from Build.
struct Collision
{
int type;
int index;
int exbits;
int legacyVal; // should be removed later, but needed for converting back for unadjusted code.
DExhumedActor* actor;
Collision() = default;
explicit Collision(int legacyval) { setFromEngine(legacyval); }
// need forward declarations of these.
int actorIndex(DExhumedActor*);
DExhumedActor* Actor(int);
int setNone()
{
type = kHitNone;
index = -1;
exbits = 0;
legacyVal = 0;
actor = nullptr;
return kHitNone;
}
int setSector(int num)
{
type = kHitSector;
index = num;
exbits = 0;
legacyVal = type | index;
actor = nullptr;
return kHitSector;
}
int setWall(int num)
{
type = kHitWall;
index = num;
exbits = 0;
legacyVal = type | index;
actor = nullptr;
return kHitWall;
}
int setSprite(DExhumedActor* num)
{
type = kHitSprite;
index = -1;
exbits = 0;
legacyVal = type | actorIndex(num);
actor = num;
return kHitSprite;
}
int setFromEngine(int value)
{
legacyVal = value;
type = value & kHitTypeMask;
exbits = value & kHitAuxMask;
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()
{
return &::wall[index];
}
sectortype* sector()
{
return &::sector[index];
}
};
class DExhumedActor : public DCoreActor
{
@ -127,21 +52,11 @@ public:
extern DExhumedActor exhumedActors[MAXSPRITES];
inline DExhumedActor* Collision::Actor(int i)
{
return &exhumedActors[i];
}
inline int Collision::actorIndex(DExhumedActor* a)
{
return a->GetSpriteIndex();
}
inline DExhumedActor* DExhumedActor::base() { return exhumedActors; }
// subclassed to add a game specific actor() method
using HitInfo = THitInfo<DExhumedActor>;
using Collision = TCollision<DExhumedActor>;
// Iterator wrappers that return an actor pointer, not an index.
class ExhumedStatIterator : public StatIterator

View file

@ -477,10 +477,10 @@ void AIFish::Tick(RunListEvent* ev)
else if (coll.type == kHitSprite)
{
auto pHitSpr = &coll.actor->s();
auto pHitSpr = &coll.actor()->s();
if (pHitSpr->statnum == 100)
{
pActor->pTarget = coll.actor;
pActor->pTarget = coll.actor();
pSprite->ang = GetMyAngle(pHitSpr->x - pSprite->x, pHitSpr->y - pSprite->y);
if (nAction != 3)
@ -491,7 +491,7 @@ void AIFish::Tick(RunListEvent* ev)
if (!pActor->nFrame)
{
runlist_DamageEnemy(coll.actor, pActor, 2);
runlist_DamageEnemy(coll.actor(), pActor, 2);
}
}
}

View file

@ -82,7 +82,7 @@ void ThrowGrenade(int nPlayer, int, int, int ecx, int push1)
auto nMov = movesprite(pActor, bcos(nAngle) * (pPlayerSprite->clipdist << 3), bsin(nAngle) * (pPlayerSprite->clipdist << 3), ecx, 0, 0, CLIPMASK1);
if (nMov.type == kHitWall)
{
nAngle = GetWallNormal(nMov.wall());
nAngle = GetWallNormal(nMov.hitWall);
BounceGrenade(pActor, nAngle);
}
}
@ -330,11 +330,11 @@ void AIGrenade::Tick(RunListEvent* ev)
// loc_2CF60:
if (nMov.type == kHitWall)
{
BounceGrenade(pActor, GetWallNormal(nMov.wall()));
BounceGrenade(pActor, GetWallNormal(nMov.hitWall));
}
else if (nMov.type == kHitSprite)
{
BounceGrenade(pActor, nMov.actor->s().ang);
BounceGrenade(pActor, nMov.actor()->s().ang);
}
pActor->nHealth = 0;

View file

@ -264,7 +264,8 @@ Collision CheckCloseRange(int nPlayer, int *x, int *y, int *z, sectortype* *ppSe
DPrintf(DMSG_WARNING, "%s %d: overflow\n", __func__, __LINE__);
sqrtNum = INT_MAX;
}
Collision c(0);
Collision c;
c.setNone();
if (ksqrt(sqrtNum) >= ecx)
return c;
@ -726,7 +727,7 @@ loc_flag:
}
else if (cRange.type == kHitSprite)
{
auto pActor2 = cRange.actor;
auto pActor2 = cRange.actor();
auto pSprite2 = &pActor2->s();
if (pSprite2->cstat & 0x50)

View file

@ -325,7 +325,7 @@ void AILavaDude::Tick(RunListEvent* ev)
}
else if (coll.type == kHitSprite)
{
if (coll.actor == pTarget)
if (coll.actor() == pTarget)
{
int nAng = getangle(pTarget->s().x - pSprite->x, pTarget->s().y - pSprite->y);
if (AngleDiff(pSprite->ang, nAng) < 64)

View file

@ -307,7 +307,7 @@ void AILion::Tick(RunListEvent* ev)
}
else if (nMov.type == kHitSprite)
{
if (nMov.actor == pTarget)
if (nMov.actor() == pTarget)
{
if (pSprite->cstat & 0x8000)
{
@ -443,13 +443,13 @@ void AILion::Tick(RunListEvent* ev)
if (nMov.type == kHitWall)
{
pActor->nAction = 7;
pSprite->ang = (GetWallNormal(nMov.wall()) + 1024) & kAngleMask;
pSprite->ang = (GetWallNormal(nMov.hitWall) + 1024) & kAngleMask;
pActor->nCount = RandomSize(4);
return;
}
else if (nMov.type == kHitSprite)
{
if (nMov.actor == pTarget)
if (nMov.actor() == pTarget)
{
int nAng = getangle(pTarget->s().x - pSprite->x, pTarget->s().y - pSprite->y);
if (AngleDiff(pSprite->ang, nAng) < 64)

View file

@ -233,7 +233,7 @@ int BelowNear(DExhumedActor* pActor, int x, int y, int walldist)
if (loHit.type == kHitSprite)
{
z2 = loHit.actor->s().z;
z2 = loHit.actor()->s().z;
}
else
{
@ -309,7 +309,8 @@ Collision movespritez(DExhumedActor* pActor, int z, int height, int, int clipdis
pSprite->cstat &= ~CSTAT_SPRITE_BLOCK;
Collision nRet(0);
Collision nRet;
nRet.setNone();
int nSectFlags = pSector->Flag;
@ -381,14 +382,14 @@ Collision movespritez(DExhumedActor* pActor, int z, int height, int, int clipdis
if (loHit.type == kHitSprite)
{
// Path A
auto pFloorSprite = &loHit.actor->s();
auto pFloorSprite = &loHit.actor()->s();
if (pSprite->statnum == 100 && pFloorSprite->statnum != 0 && pFloorSprite->statnum < 100)
{
int nDamage = (z >> 9);
if (nDamage)
{
runlist_DamageEnemy(loHit.actor, pActor, nDamage << 1);
runlist_DamageEnemy(loHit.actor(), pActor, nDamage << 1);
}
pSprite->zvel = -z;
@ -530,8 +531,8 @@ Collision movesprite(DExhumedActor* pActor, int dx, int dy, int dz, int ceildist
CheckSectorFloor(overridesect, pSprite->z, &dx, &dy);
}
int colv = clipmove(&pSprite->pos, &pSector, dx, dy, nClipDist, nSpriteHeight, flordist, clipmask);
Collision coll(colv);
Collision coll;
clipmove(pSprite->pos, &pSector, dx, dy, nClipDist, nSpriteHeight, flordist, clipmask, coll);
if (coll.type != kHitNone) // originally this or'ed the two values which can create unpredictable bad values in some edge cases.
{
coll.exbits = nRet.exbits;
@ -645,7 +646,9 @@ Collision MoveCreatureWithCaution(DExhumedActor* pActor)
pSprite->ang = (pSprite->ang + 256) & kAngleMask;
pSprite->xvel = bcos(pSprite->ang, -2);
pSprite->yvel = bsin(pSprite->ang, -2);
return Collision(0);
Collision c;
c.setNone();
return c;
}
}
@ -915,7 +918,8 @@ void MoveSector(sectortype* pSector, int nAngle, int *nXVel, int *nYVel)
}
auto pSectorB = pSector;
clipmove(&pos, &pSectorB, nXVect, nYVect, pBlockInfo->field_8, 0, 0, CLIPMASK1);
Collision scratch;
clipmove(pos, &pSectorB, nXVect, nYVect, pBlockInfo->field_8, 0, 0, CLIPMASK1, scratch);
int yvect = pos.y - y_b;
int xvect = pos.x - x_b;
@ -931,7 +935,8 @@ void MoveSector(sectortype* pSector, int nAngle, int *nXVel, int *nYVel)
{
pos = { x_b, y_b, nZVal };
clipmove(&pos, &pSectorB, nXVect, nYVect, pBlockInfo->field_8, 0, 0, CLIPMASK1);
Collision scratch;
clipmove(pos, &pSectorB, nXVect, nYVect, pBlockInfo->field_8, 0, 0, CLIPMASK1, scratch);
int ebx = pos.x;
int ecx = x_b;
@ -997,7 +1002,8 @@ void MoveSector(sectortype* pSector, int nAngle, int *nXVel, int *nYVel)
pos.y = sp->y;
pSectorB = pSector;
clipmove(&pos, &pSectorB, -xvect, -yvect, 4 * sp->clipdist, 0, 0, CLIPMASK0);
Collision scratch;
clipmove(pos, &pSectorB, -xvect, -yvect, 4 * sp->clipdist, 0, 0, CLIPMASK0, scratch);
if (pSectorB) {
ChangeActorSect(pActor, pSectorB);
@ -1015,10 +1021,11 @@ void MoveSector(sectortype* pSector, int nAngle, int *nXVel, int *nYVel)
pos = pSprite->pos;
pSectorB = pNextSector;
clipmove(&pos, &pSectorB,
Collision scratch;
clipmove(pos, &pSectorB,
-xvect - (bcos(nAngle) * (4 * pSprite->clipdist)),
-yvect - (bsin(nAngle) * (4 * pSprite->clipdist)),
4 * pSprite->clipdist, 0, 0, CLIPMASK0);
4 * pSprite->clipdist, 0, 0, CLIPMASK0, scratch);
if (pSectorB != pNextSector && (pSectorB == pSector || pNextSector == pSector))
@ -1062,7 +1069,8 @@ void MoveSector(sectortype* pSector, int nAngle, int *nXVel, int *nYVel)
if (pSprite->statnum >= 99 && nZVal == pSprite->z && !(pSprite->cstat & 0x8000))
{
pSectorB = pSector;
clipmove(&pSprite->pos, &pSectorB, xvect, yvect, 4 * pSprite->clipdist, 5120, -5120, CLIPMASK0);
Collision scratch;
clipmove(pSprite->pos, &pSectorB, xvect, yvect, 4 * pSprite->clipdist, 5120, -5120, CLIPMASK0, scratch);
}
}
}
@ -1257,10 +1265,11 @@ void WheresMyMouth(int nPlayer, vec3_t* pos, sectortype **sectnum)
*pos = pSprite->pos;
pos->z -= height;
clipmove(pos, sectnum,
Collision scratch;
clipmove(*pos, sectnum,
bcos(pSprite->ang, 7),
bsin(pSprite->ang, 7),
5120, 1280, 1280, CLIPMASK1);
5120, 1280, 1280, CLIPMASK1, scratch);
}
void InitChunks()
@ -1462,11 +1471,11 @@ void AICreatureChunk::Tick(RunListEvent* ev)
}
else if (nVal.type == kHitSprite)
{
nAngle = nVal.actor->s().ang;
nAngle = nVal.actor()->s().ang;
}
else if (nVal.type == kHitWall)
{
nAngle = GetWallNormal(nVal.wall());
nAngle = GetWallNormal(nVal.hitWall);
}
else
{

View file

@ -280,7 +280,7 @@ void AIMummy::Tick(RunListEvent* ev)
case kHitSprite:
{
if (nMov.actor == pTarget)
if (nMov.actor() == pTarget)
{
int nAngle = getangle(pTarget->s().x - pSprite->x, pTarget->s().y - pSprite->y);
if (AngleDiff(pSprite->ang, nAngle) < 64)

View file

@ -882,7 +882,8 @@ void AIPlayer::Tick(RunListEvent* ev)
zVel = pPlayerSprite->zvel;
Collision nMove(0);
Collision nMove;
nMove.setNone();
if (bSlipMode)
{
pPlayerSprite->x += (x >> 14);
@ -1014,13 +1015,13 @@ void AIPlayer::Tick(RunListEvent* ev)
if (nMove.type == kHitSector)
{
sect = nMove.sector();
sect = nMove.hitSector;
// Hm... Normal calculation here was broken.
}
else //if (nMove.type == kHitWall)
{
sect = nMove.wall()->nextSector();
nNormal = GetWallNormal(nMove.wall());
sect = nMove.hitWall->nextSector();
nNormal = GetWallNormal(nMove.hitWall);
}
if (sect != nullptr)

View file

@ -575,10 +575,10 @@ void AIQueenEgg::Tick(RunListEvent* ev)
default:
return;
case kHitWall:
nAngle = GetWallNormal(nMov.wall());
nAngle = GetWallNormal(nMov.hitWall);
break;
case kHitSprite:
nAngle = nMov.actor->s().ang;
nAngle = nMov.actor()->s().ang;
break;
}
@ -608,9 +608,9 @@ void AIQueenEgg::Tick(RunListEvent* ev)
switch (nMov.type)
{
case kHitSprite:
if (nMov.actor->s().statnum != 121)
if (nMov.actor()->s().statnum != 121)
{
runlist_DamageEnemy(nMov.actor, pActor, 5);
runlist_DamageEnemy(nMov.actor(), pActor, 5);
}
[[fallthrough]];
case kHitWall:
@ -810,8 +810,8 @@ void AIQueenHead::Tick(RunListEvent* ev)
if (nMov.exbits == 0)
{
if (nMov.type == kHitSprite) nNewAng = nMov.actor->s().ang;
else if (nMov.type == kHitWall) nNewAng = GetWallNormal(nMov.wall());
if (nMov.type == kHitSprite) nNewAng = nMov.actor()->s().ang;
else if (nMov.type == kHitWall) nNewAng = GetWallNormal(nMov.hitWall);
}
else if (nMov.exbits == kHitAux2)
{
@ -895,7 +895,7 @@ void AIQueenHead::Tick(RunListEvent* ev)
if (nMov.type == kHitSprite)
{
if (nMov.actor == pTarget)
if (nMov.actor() == pTarget)
{
runlist_DamageEnemy(pTarget, pActor, 10);
D3PlayFX(StaticSound[kSoundQTail] | 0x2000, pActor);
@ -1305,7 +1305,7 @@ void AIQueen::Tick(RunListEvent* ev)
switch (nMov.type)
{
case kHitSprite:
if ((si == 2) && (nMov.actor == pTarget))
if ((si == 2) && (nMov.actor() == pTarget))
{
runlist_DamageEnemy(pTarget, pActor, 5);
break;

View file

@ -285,7 +285,7 @@ void AIRex::Tick(RunListEvent* ev)
{
case kHitSprite:
{
if (nMov.actor == pTarget)
if (nMov.actor() == pTarget)
{
PlotCourseToSprite(pActor, pTarget);
pActor->nAction = 4;
@ -341,20 +341,20 @@ void AIRex::Tick(RunListEvent* ev)
pActor->nAction = 3;
pActor->nFrame = 0;
auto pSprite2 = &nMov.actor->s();
auto pSprite2 = &nMov.actor()->s();
if (pSprite2->statnum && pSprite2->statnum < 107)
{
int nAngle = pSprite->ang;
runlist_DamageEnemy(nMov.actor, pActor, 15);
runlist_DamageEnemy(nMov.actor(), pActor, 15);
int xVel = bcos(nAngle) * 15;
int yVel = bsin(nAngle) * 15;
if (pSprite2->statnum == 100)
{
auto nPlayer = GetPlayerFromActor(nMov.actor);
auto nPlayer = GetPlayerFromActor(nMov.actor());
PlayerList[nPlayer].nXDamage += (xVel << 4);
PlayerList[nPlayer].nYDamage += (yVel << 4);
pSprite2->zvel = -3584;

View file

@ -274,7 +274,7 @@ void AIRoach::Tick(RunListEvent* ev)
if (nMov.type == kHitSprite)
{
if (nMov.actor == pTarget)
if (nMov.actor() == pTarget)
{
// repeated below
pActor->nIndex = RandomSize(2) + 1;

View file

@ -258,7 +258,7 @@ void AIScorp::Tick(RunListEvent* ev)
auto nMov = MoveCreatureWithCaution(pActor);
if (nMov.type == kHitSprite)
{
if (pTarget == nMov.actor)
if (pTarget == nMov.actor())
{
int nAngle = getangle(pTarget->s().x - pSprite->x, pTarget->s().y - pSprite->y);
if (AngleDiff(pSprite->ang, nAngle) < 64)

View file

@ -420,7 +420,7 @@ void AISet::Tick(RunListEvent* ev)
if (nMov.type == kHitWall)
{
auto pSector = nMov.wall()->nextSector();
auto pSector = nMov.hitWall->nextSector();
if (pSector)
{
@ -445,7 +445,7 @@ void AISet::Tick(RunListEvent* ev)
}
else if (nMov.type == kHitSprite)
{
if (pTarget == nMov.actor)
if (pTarget == nMov.actor())
{
int nAng = getangle(pTarget->s().x - pSprite->x, pTarget->s().y - pSprite->y);
if (AngleDiff(pSprite->ang, nAng) < 64)

View file

@ -314,7 +314,7 @@ void AISpider::Tick(RunListEvent* ev)
}
case kHitSprite:
{
if (nMov.actor == pTarget)
if (nMov.actor() == pTarget)
{
int nAng = getangle(pTarget->s().x - sp->x, pTarget->s().y - sp->y);
if (AngleDiff(sp->ang, nAng) < 64)

View file

@ -292,7 +292,7 @@ void AIWasp::Tick(RunListEvent* ev)
case kHitSprite:
{
if (nChaseVal.actor == pTarget)
if (nChaseVal.actor() == pTarget)
{
pSprite->xvel = 0;
pSprite->yvel = 0;