diff --git a/source/common/utility/vectors.h b/source/common/utility/vectors.h index 5a38fb8b5..b8a563ca8 100644 --- a/source/common/utility/vectors.h +++ b/source/common/utility/vectors.h @@ -1312,6 +1312,11 @@ public: return Degrees_ / other; } + constexpr double operator/ (TAngle other) const + { + return Degrees_ / other.Degrees_; + } + // Should the comparisons consider an epsilon value? constexpr bool operator< (TAngle other) const { diff --git a/source/games/exhumed/src/aistuff.h b/source/games/exhumed/src/aistuff.h index ced4ac3f7..517785b42 100644 --- a/source/games/exhumed/src/aistuff.h +++ b/source/games/exhumed/src/aistuff.h @@ -231,7 +231,7 @@ void CheckSectorFloor(sectortype* pSector, double z, DVector2& xy); int GetAngleToSprite(DExhumedActor* nSprite1, DExhumedActor* nSprite2); int GetWallNormal(walltype* nWall); void MoveSector(sectortype* pSector, DAngle nAngle, DVector2& vel); -Collision AngleChase(DExhumedActor* nSprite, DExhumedActor* nSprite2, int ebx, int ecx, int push1); +Collision AngleChase(DExhumedActor* nSprite, DExhumedActor* nSprite2, int ebx, int ecx, DAngle push1); void SetQuake(DExhumedActor* nSprite, int nVal); // mummy diff --git a/source/games/exhumed/src/bullet.cpp b/source/games/exhumed/src/bullet.cpp index 8e50842cc..5ad2ddca4 100644 --- a/source/games/exhumed/src/bullet.cpp +++ b/source/games/exhumed/src/bullet.cpp @@ -310,7 +310,7 @@ int MoveBullet(int nBullet) BulletList[nBullet].pEnemy = nullptr; else { - coll = AngleChase(pActor, pEnemyActor, pBullet->field_10, 0, 16); + coll = AngleChase(pActor, pEnemyActor, pBullet->field_10, 0, DAngle22_5 / 8); goto MOVEEND; } } diff --git a/source/games/exhumed/src/exhumed.cpp b/source/games/exhumed/src/exhumed.cpp index e1f8f3569..b1d69cf88 100644 --- a/source/games/exhumed/src/exhumed.cpp +++ b/source/games/exhumed/src/exhumed.cpp @@ -618,7 +618,7 @@ void DExhumedActor::Serialize(FSerializer& arc) ("index2", nIndex2) ("channel", nChannel) ("damage", nDamage) - ("angle2", angle2) + ("angle2", pitch) ("turn", nTurn) ("x", x) diff --git a/source/games/exhumed/src/exhumedactor.h b/source/games/exhumed/src/exhumedactor.h index 08a45763a..78199daec 100644 --- a/source/games/exhumed/src/exhumedactor.h +++ b/source/games/exhumed/src/exhumedactor.h @@ -32,7 +32,7 @@ public: union { int16_t nIndex2; int16_t nAngle2; }; // index2 is for scorpion, angle2 is for wasp. union { int16_t nChannel; int16_t nVel; }; // channel is for scorpion, vel is for wasp. union { int16_t nDamage; int16_t nAction2; }; // nAction2 is for the queen. - DAngle angle2; // used by AngleChase + DAngle pitch; // used by AngleChase // for the grenade. int nTurn; diff --git a/source/games/exhumed/src/move.cpp b/source/games/exhumed/src/move.cpp index 261faa697..efdbea5a0 100644 --- a/source/games/exhumed/src/move.cpp +++ b/source/games/exhumed/src/move.cpp @@ -908,7 +908,7 @@ void SetQuake(DExhumedActor* pActor, int nVal) } } -Collision AngleChase(DExhumedActor* pActor, DExhumedActor* pActor2, int ebx, int ecx, int push1) +Collision AngleChase(DExhumedActor* pActor, DExhumedActor* pActor2, int threshold, int zbob, DAngle push1) { int nClipType = pActor->spr.statnum != 107; @@ -920,75 +920,50 @@ Collision AngleChase(DExhumedActor* pActor, DExhumedActor* pActor2, int ebx, int nClipType = CLIPMASK0; } - int nAngle; + DAngle nAngle; if (pActor2 == nullptr) { - pActor->angle2 = nullAngle; - nAngle = pActor->int_ang(); + pActor->pitch = nullAngle; + nAngle = pActor->spr.angle; } else { - int nHeight = tileHeight(pActor2->spr.picnum) * pActor2->spr.yrepeat * 2; - + double nHeight = GetActorHeightF(pActor2) / 2; + int nHeight1 = GetActorHeight(pActor2) / 2; auto vect = pActor2->spr.pos.XY() - pActor->spr.pos.XY(); - int nMyAngle = getangle(vect); + DAngle nMyAngle = VecToAngle(vect); + double nSqrt = vect.Length(); + DAngle nPitch = VecToAngle(nSqrt, (pActor2->spr.pos.Z - nHeight - pActor->spr.pos.Z) / 16.); - int nSqrt = int(vect.Length() * worldtoint); + DAngle nAngDelta = deltaangle(pActor->spr.angle, nMyAngle); - int var_18 = getangle(nSqrt, ((pActor2->int_pos().Z - nHeight) - pActor->int_pos().Z) >> 8); - - int nAngDelta = AngleDelta(pActor->int_ang(), nMyAngle, 1024); - int nAngDelta2 = abs(nAngDelta); - - if (nAngDelta2 > 63) + if (abs(nAngDelta) >= DAngle22_5 / 2) { - nAngDelta2 = abs(nAngDelta >> 6); + int nAngDelta2 = abs(nAngDelta.Buildang() >> 6); - ebx /= nAngDelta2; + threshold /= nAngDelta2; - if (ebx < 5) { - ebx = 5; + if (threshold < 5) { + threshold = 5; } } - int nAngDeltaC = abs(nAngDelta); - - if (nAngDeltaC > push1) - { - if (nAngDelta >= 0) - nAngDelta = push1; - else - nAngDelta = -push1; - } - - nAngle = (nAngDelta + pActor->int_ang()) & kAngleMask; - int nAngDeltaD = AngleDelta(pActor->angle2.Buildang(), var_18, 24); - - pActor->angle2 = DAngle::fromBuild((pActor->angle2.Buildang() + nAngDeltaD) & kAngleMask); + nAngDelta = clamp(nAngDelta, -push1, push1); + nAngle = (nAngDelta + pActor->spr.angle).Normalized360(); + auto nPitchDelta = clamp(deltaangle(pActor->pitch, nPitch), -DAngle22_5 / 5, DAngle22_5 / 5); + pActor->pitch = (pActor->pitch + nPitchDelta).Normalized180(); } - pActor->set_int_ang(nAngle); + pActor->spr.angle = nAngle; - int eax = abs(bcos(pActor->angle2.Buildang())); + auto cospitch = pActor->pitch.Cos(); - int x = ((bcos(nAngle) * ebx) >> 14) * eax; - int y = ((bsin(nAngle) * ebx) >> 14) * eax; + auto vec = nAngle.ToVector() * threshold * (1/64.) * cospitch; + auto veclen = vec.Length(); + double zz = g_sindeg(pActor->vel.Z * 45) * veclen; - int xshift = x >> 8; - int yshift = y >> 8; - - uint32_t sqrtNum = xshift * xshift + yshift * yshift; - - if (sqrtNum > INT_MAX) - { - DPrintf(DMSG_WARNING, "%s %d: overflow\n", __func__, __LINE__); - sqrtNum = INT_MAX; - } - - int z = bsin(pActor->int_zvel()) * ksqrt(sqrtNum); - - return movesprite(pActor, x >> 2, y >> 2, (z >> 13) + bsin(ecx, -5), 0, 0, nClipType); + return movesprite(pActor, FloatToFixed<18>(vec.X), FloatToFixed<18>(vec.Y), zz * 4096 + BobVal(zbob) * 512, 0, 0, nClipType); } int GetWallNormal(walltype* pWall) @@ -1000,10 +975,10 @@ int GetWallNormal(walltype* pWall) DVector3 WheresMyMouth(int nPlayer, sectortype **sectnum) { auto pActor = PlayerList[nPlayer].pActor; - double height = GetActorHeight(pActor) * 0.5; + double height = GetActorHeightF(pActor) * 0.5; *sectnum = pActor->sector(); - auto pos = pActor->spr.pos.plusZ(-height * zinttoworld); + auto pos = pActor->spr.pos.plusZ(-height); Collision scratch; clipmove(pos, sectnum, diff --git a/source/games/exhumed/src/queen.cpp b/source/games/exhumed/src/queen.cpp index ce251dfbf..c14895195 100644 --- a/source/games/exhumed/src/queen.cpp +++ b/source/games/exhumed/src/queen.cpp @@ -287,7 +287,7 @@ Collision QueenAngleChase(DExhumedActor* pActor, DExhumedActor* pActor2, int val if (pActor2 == nullptr) { - pActor->angle2 = nullAngle; + pActor->pitch = nullAngle; nAngle = pActor->int_ang(); } else @@ -322,12 +322,12 @@ Collision QueenAngleChase(DExhumedActor* pActor, DExhumedActor* pActor2, int val nAngle = (nAngDelta + pActor->int_ang()) & kAngleMask; - pActor->angle2 = DAngle::fromBuild((AngleDelta(pActor->angle2.Buildang(), var_14, 24) + pActor->angle2.Buildang()) & kAngleMask); + pActor->pitch = DAngle::fromBuild((AngleDelta(pActor->pitch.Buildang(), var_14, 24) + pActor->pitch.Buildang()) & kAngleMask); } pActor->set_int_ang(nAngle); - int da = pActor->angle2.Buildang(); + int da = pActor->pitch.Buildang(); int x = abs(bcos(da)); int v26 = x * ((val1 * bcos(nAngle)) >> 14); diff --git a/source/games/exhumed/src/snake.cpp b/source/games/exhumed/src/snake.cpp index b9ee2091c..a733f88af 100644 --- a/source/games/exhumed/src/snake.cpp +++ b/source/games/exhumed/src/snake.cpp @@ -324,7 +324,7 @@ void AISnake::Tick(RunListEvent* ev) zVal = pActor->int_pos().Z; - nMov = AngleChase(pActor, pEnemySprite, 1200, SnakeList[nSnake].nAngle, 32); + nMov = AngleChase(pActor, pEnemySprite, 1200, SnakeList[nSnake].nAngle, DAngle22_5 / 4); zVal = pActor->int_pos().Z - zVal; } diff --git a/source/games/exhumed/src/wasp.cpp b/source/games/exhumed/src/wasp.cpp index d23f3e129..8abad9d2d 100644 --- a/source/games/exhumed/src/wasp.cpp +++ b/source/games/exhumed/src/wasp.cpp @@ -241,7 +241,7 @@ void AIWasp::Tick(RunListEvent* ev) } else { - pActor->angle2 = nullAngle; + pActor->pitch = nullAngle; pActor->vel.Z = 0; pActor->nAction = 1; pActor->nFrame = 0; @@ -270,7 +270,7 @@ void AIWasp::Tick(RunListEvent* ev) return; } - auto nChaseVal = AngleChase(pActor, pTarget, pActor->nVel, 0, 16); + auto nChaseVal = AngleChase(pActor, pTarget, pActor->nVel, 0, DAngle22_5 / 8); switch (nChaseVal.type) {