From 2b5422cc533d12d816a7fc550260c2e718bfdc1b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 4 Sep 2022 00:38:26 +0200 Subject: [PATCH] - floatified USER::goalAng --- source/common/utility/vectors.h | 1 + source/games/blood/src/actor.cpp | 5 +- source/games/blood/src/ai.cpp | 60 +++++++------- source/games/blood/src/ai.h | 8 +- source/games/blood/src/aibat.cpp | 24 +++--- source/games/blood/src/aibeast.cpp | 26 +++--- source/games/blood/src/aiboneel.cpp | 22 ++--- source/games/blood/src/aiburn.cpp | 6 +- source/games/blood/src/aicaleb.cpp | 18 ++-- source/games/blood/src/aicerber.cpp | 8 +- source/games/blood/src/aicult.cpp | 6 +- source/games/blood/src/aigarg.cpp | 24 +++--- source/games/blood/src/aighost.cpp | 24 +++--- source/games/blood/src/aigilbst.cpp | 18 ++-- source/games/blood/src/aihand.cpp | 6 +- source/games/blood/src/aihound.cpp | 6 +- source/games/blood/src/aiinnoc.cpp | 6 +- source/games/blood/src/aipod.cpp | 6 +- source/games/blood/src/airat.cpp | 6 +- source/games/blood/src/aispid.cpp | 6 +- source/games/blood/src/aitchern.cpp | 8 +- source/games/blood/src/aiunicult.cpp | 72 ++++++++-------- source/games/blood/src/aiunicult.h | 2 +- source/games/blood/src/aizomba.cpp | 10 +-- source/games/blood/src/aizombf.cpp | 6 +- source/games/blood/src/db.cpp | 2 +- source/games/blood/src/loadsave.cpp | 2 +- source/games/blood/src/mapstructs.h | 2 +- source/games/blood/src/nnexts.cpp | 119 ++++++++++++++------------- 29 files changed, 258 insertions(+), 251 deletions(-) diff --git a/source/common/utility/vectors.h b/source/common/utility/vectors.h index 017d1a520..df032037f 100644 --- a/source/common/utility/vectors.h +++ b/source/common/utility/vectors.h @@ -1692,6 +1692,7 @@ typedef TMatrix3x3 DMatrix3x3; typedef TAngle DAngle; constexpr DAngle nullAngle = DAngle::fromDeg(0.); +constexpr DAngle minAngle = DAngle::fromDeg(1. / 65536.); constexpr FAngle nullFAngle = FAngle::fromDeg(0.); constexpr DAngle DAngle22_5 = DAngle::fromDeg(22.5); diff --git a/source/games/blood/src/actor.cpp b/source/games/blood/src/actor.cpp index ea32dcbe6..d720a18ff 100644 --- a/source/games/blood/src/actor.cpp +++ b/source/games/blood/src/actor.cpp @@ -3965,7 +3965,7 @@ static void actImpactMissile(DBloodActor* missileActor, int hitCode) missileActor->spr.picnum = 2123; missileActor->SetTarget(actorHit); missileActor->xspr.TargetPos.Z = (missileActor->spr.pos.Z - actorHit->spr.pos.Z); - missileActor->xspr._goalAng = getangle(missileActor->spr.pos.XY() - actorHit->spr.pos.XY()) - actorHit->int_ang(); + missileActor->xspr.goalAng = VecToAngle(missileActor->spr.pos.XY() - actorHit->spr.pos.XY()) - actorHit->spr.angle; missileActor->xspr.state = 1; actPostSprite(missileActor, kStatFlare); missileActor->spr.cstat &= ~CSTAT_SPRITE_BLOCK_ALL; @@ -6139,8 +6139,7 @@ void actCheckFlares() if (target->hasX() && target->xspr.health > 0) { DVector3 pos = target->spr.pos; - pos.X += mulscale30r(Cos(actor->xspr._goalAng + target->int_ang()), target->spr.clipdist * 2) * inttoworld; - pos.Y += mulscale30r(Sin(actor->xspr._goalAng + target->int_ang()), target->spr.clipdist * 2) * inttoworld; + pos.XY() += actor->xspr.goalAng.ToVector() * target->spr.clipdist * 2 * inttoworld; pos.Z += actor->xspr.TargetPos.Z; SetActor(actor, pos); actor->vel = target->vel; diff --git a/source/games/blood/src/ai.cpp b/source/games/blood/src/ai.cpp index 43bd24a4b..18a0a6ac0 100644 --- a/source/games/blood/src/ai.cpp +++ b/source/games/blood/src/ai.cpp @@ -247,43 +247,43 @@ bool CanMove(DBloodActor* actor, DBloodActor* target, int nAngle, int nRange) // //--------------------------------------------------------------------------- -void aiChooseDirection(DBloodActor* actor, int a3) +void aiChooseDirection(DBloodActor* actor, DAngle direction) { assert(actor->spr.type >= kDudeBase && actor->spr.type < kDudeMax); - int vc = getincangle(actor->int_ang(), a3); - int nCos = Cos(actor->int_ang()); - int nSin = Sin(actor->int_ang()); - int dx = actor->int_vel().X; - int dy = actor->int_vel().Y; - int t1 = DMulScale(dx, nCos, dy, nSin, 30); - int vsi = ((t1 * 15) >> 12) / 2; - int v8 = 341; - if (vc < 0) - v8 = -341; - if (CanMove(actor, actor->GetTarget(), actor->int_ang() + vc, vsi)) - actor->xspr._goalAng = actor->int_ang() + vc; - else if (CanMove(actor, actor->GetTarget(), actor->int_ang() + vc / 2, vsi)) - actor->xspr._goalAng = actor->int_ang() + vc / 2; - else if (CanMove(actor, actor->GetTarget(), actor->int_ang() - vc / 2, vsi)) - actor->xspr._goalAng = actor->int_ang() - vc / 2; - else if (CanMove(actor, actor->GetTarget(), actor->int_ang() + v8, vsi)) - actor->xspr._goalAng = actor->int_ang() + v8; - else if (CanMove(actor, actor->GetTarget(), actor->int_ang(), vsi)) - actor->xspr._goalAng = actor->int_ang(); - else if (CanMove(actor, actor->GetTarget(), actor->int_ang() - v8, vsi)) - actor->xspr._goalAng = actor->int_ang() - v8; + DAngle vc = deltaangle(actor->spr.angle, direction); + double nCos = actor->spr.angle.Cos(); + double nSin = actor->spr.angle.Sin(); + double t1 = actor->vel.X * nCos + actor->vel.Y * nSin; + + int range = FloatToFixed(t1 * (15 / 8192.)); + DAngle v8 = vc > nullAngle ? DAngle180 / 3 : -DAngle180 / 3; + + if (CanMove(actor, actor->GetTarget(), actor->spr.angle + vc, range)) + actor->xspr.goalAng = actor->spr.angle + vc; + else if (CanMove(actor, actor->GetTarget(), actor->spr.angle + vc / 2, range)) + actor->xspr.goalAng = actor->spr.angle + vc / 2; + else if (CanMove(actor, actor->GetTarget(), actor->spr.angle - vc / 2, range)) + actor->xspr.goalAng = actor->spr.angle - vc / 2; + else if (CanMove(actor, actor->GetTarget(), actor->spr.angle + v8, range)) + actor->xspr.goalAng = actor->spr.angle + v8; + else if (CanMove(actor, actor->GetTarget(), actor->spr.angle, range)) + actor->xspr.goalAng = actor->spr.angle; + else if (CanMove(actor, actor->GetTarget(), actor->spr.angle - v8, range)) + actor->xspr.goalAng = actor->spr.angle - v8; //else if (actor->spr.flags&2) //actor->xspr.goalAng = actor->spr.angle+341; else // Weird.. - actor->xspr._goalAng = actor->int_ang() + 341; + actor->xspr.goalAng = actor->spr.angle + DAngle180/3; if (Chance(0x8000)) actor->xspr.dodgeDir = 1; else actor->xspr.dodgeDir = -1; - if (!CanMove(actor, actor->GetTarget(), actor->int_ang() + actor->xspr.dodgeDir * 512, 512)) + + actor->xspr.goalAng = actor->xspr.goalAng.Normalized360(); + if (!CanMove(actor, actor->GetTarget(), actor->spr.angle + DAngle90 * actor->xspr.dodgeDir, 512)) { actor->xspr.dodgeDir = -actor->xspr.dodgeDir; - if (!CanMove(actor, actor->GetTarget(), actor->int_ang() + actor->xspr.dodgeDir * 512, 512)) + if (!CanMove(actor, actor->GetTarget(), actor->spr.angle + DAngle90 * actor->xspr.dodgeDir, 512)) actor->xspr.dodgeDir = 0; } } @@ -298,7 +298,7 @@ void aiMoveForward(DBloodActor* actor) { assert(actor->spr.type >= kDudeBase && actor->spr.type < kDudeMax); DUDEINFO* pDudeInfo = getDudeInfo(actor->spr.type); - auto nAng = deltaangle(actor->spr.angle, DAngle::fromBuild(actor->xspr._goalAng)); + auto nAng = deltaangle(actor->spr.angle, actor->xspr.goalAng); auto nTurnRange = DAngle::fromQ16(pDudeInfo->angSpeed << 3); actor->spr.angle += clamp(nAng, -nTurnRange, nTurnRange); if (abs(nAng) > DAngle60) @@ -317,7 +317,7 @@ void aiMoveTurn(DBloodActor* actor) { assert(actor->spr.type >= kDudeBase && actor->spr.type < kDudeMax); DUDEINFO* pDudeInfo = getDudeInfo(actor->spr.type); - auto nAng = deltaangle(actor->spr.angle, DAngle::fromBuild(actor->xspr._goalAng)); + auto nAng = deltaangle(actor->spr.angle, actor->xspr.goalAng); auto nTurnRange = DAngle::fromQ16(pDudeInfo->angSpeed << 3); actor->spr.angle += clamp(nAng, -nTurnRange, nTurnRange); } @@ -332,7 +332,7 @@ void aiMoveDodge(DBloodActor* actor) { assert(actor->spr.type >= kDudeBase && actor->spr.type < kDudeMax); DUDEINFO* pDudeInfo = getDudeInfo(actor->spr.type); - auto nAng = deltaangle(actor->spr.angle, DAngle::fromBuild(actor->xspr._goalAng)); + auto nAng = deltaangle(actor->spr.angle, actor->xspr.goalAng); auto nTurnRange = DAngle::fromQ16(pDudeInfo->angSpeed << 3); actor->spr.angle += clamp(nAng, -nTurnRange, nTurnRange); if (actor->xspr.dodgeDir) @@ -357,7 +357,7 @@ void aiActivateDude(DBloodActor* actor) assert(actor->spr.type >= kDudeBase && actor->spr.type < kDudeMax); if (!actor->xspr.state) { - aiChooseDirection(actor, getangle(actor->xspr.int_TargetPos().X - actor->int_pos().X, actor->xspr.int_TargetPos().Y - actor->int_pos().Y)); + aiChooseDirection(actor, VecToAngle(actor->xspr.TargetPos - actor->spr.pos)); actor->xspr.state = 1; } switch (actor->spr.type) diff --git a/source/games/blood/src/ai.h b/source/games/blood/src/ai.h index a3fdadd64..01b577af1 100644 --- a/source/games/blood/src/ai.h +++ b/source/games/blood/src/ai.h @@ -80,7 +80,7 @@ extern const int gCultTeslaFireChance[5]; bool dudeIsPlayingSeq(DBloodActor* pSprite, int nSeq); void aiPlay3DSound(DBloodActor* pSprite, int a2, AI_SFX_PRIORITY a3, int a4); void aiNewState(DBloodActor* actor, AISTATE *pAIState); -void aiChooseDirection(DBloodActor* actor, int a3); +void aiChooseDirection(DBloodActor* actor, DAngle a3); void aiMoveForward(DBloodActor*pXSprite); void aiMoveTurn(DBloodActor*pXSprite); void aiMoveDodge(DBloodActor *actor); @@ -97,6 +97,10 @@ void aiLookForTarget(DBloodActor* actor); void aiProcessDudes(void); void aiInit(void); void aiInitSprite(DBloodActor* pSprite); -bool CanMove(DBloodActor* pSprite, int a2, int nAngle, int nRange); +bool CanMove(DBloodActor* pSprite, DBloodActor* target, int nAngle, int nRange); +inline bool CanMove(DBloodActor* pSprite, DBloodActor* target, DAngle nAngle, int nRange) +{ + return CanMove(pSprite, target, nAngle.Buildang(), nRange); +} END_BLD_NS diff --git a/source/games/blood/src/aibat.cpp b/source/games/blood/src/aibat.cpp index f716f114c..7258ece50 100644 --- a/source/games/blood/src/aibat.cpp +++ b/source/games/blood/src/aibat.cpp @@ -85,7 +85,7 @@ static void batThinkTarget(DBloodActor* actor) else if (pDudeExtraE->thinkTime >= 10 && pDudeExtraE->active) { pDudeExtraE->thinkTime = 0; - actor->xspr._goalAng += 256; + actor->xspr.goalAng += DAngle45; aiSetTarget(actor, actor->basePoint); aiNewState(actor, &batTurn); return; @@ -127,7 +127,7 @@ static void batThinkTarget(DBloodActor* actor) static void batThinkSearch(DBloodActor* actor) { - aiChooseDirection(actor, actor->xspr._goalAng); + aiChooseDirection(actor, actor->xspr.goalAng); batThinkTarget(actor); } @@ -136,10 +136,10 @@ static void batThinkGoto(DBloodActor* actor) assert(actor->spr.type >= kDudeBase && actor->spr.type < kDudeMax); DUDEINFO* pDudeInfo = getDudeInfo(actor->spr.type); auto dvec = actor->xspr.TargetPos.XY() - actor->spr.pos.X; - int nAngle = getangle(dvec); + auto nAngle = VecToAngle(dvec); int nDist = approxDist(dvec); aiChooseDirection(actor, nAngle); - if (nDist < 512 && abs(actor->int_ang() - nAngle) < pDudeInfo->periphery) + if (nDist < 512 && absangle(actor->spr.angle, nAngle) < DAngle::fromBuild(pDudeInfo->periphery)) aiNewState(actor, &batSearch); batThinkTarget(actor); } @@ -156,7 +156,7 @@ static void batThinkPonder(DBloodActor* actor) if (!actor->ValidateTarget(__FUNCTION__)) return; auto pTarget = actor->GetTarget(); auto dvec = pTarget->spr.pos.XY() - actor->spr.pos.XY(); - aiChooseDirection(actor, getangle(dvec)); + aiChooseDirection(actor, VecToAngle(dvec)); if (pTarget->xspr.health == 0) { aiNewState(actor, &batSearch); @@ -200,7 +200,7 @@ static void batMoveDodgeUp(DBloodActor* actor) { assert(actor->spr.type >= kDudeBase && actor->spr.type < kDudeMax); DUDEINFO* pDudeInfo = getDudeInfo(actor->spr.type); - auto nAng = deltaangle(actor->spr.angle, DAngle::fromBuild(actor->xspr._goalAng)); + auto nAng = deltaangle(actor->spr.angle, actor->xspr.goalAng); auto nTurnRange = DAngle::fromQ16(pDudeInfo->angSpeed << 3); actor->spr.angle += clamp(nAng, -nTurnRange, nTurnRange); AdjustVelocity(actor, ADJUSTER{ @@ -217,7 +217,7 @@ static void batMoveDodgeDown(DBloodActor* actor) { assert(actor->spr.type >= kDudeBase && actor->spr.type < kDudeMax); DUDEINFO* pDudeInfo = getDudeInfo(actor->spr.type); - auto nAng = deltaangle(actor->spr.angle, DAngle::fromBuild(actor->xspr._goalAng)); + auto nAng = deltaangle(actor->spr.angle, actor->xspr.goalAng); auto nTurnRange = DAngle::fromQ16(pDudeInfo->angSpeed << 3); actor->spr.angle += clamp(nAng, -nTurnRange, nTurnRange); if (actor->xspr.dodgeDir == 0) @@ -245,7 +245,7 @@ static void batThinkChase(DBloodActor* actor) auto pTarget = actor->GetTarget(); auto dvec = pTarget->spr.pos.XY() - actor->spr.pos.XY(); - aiChooseDirection(actor, getangle(dvec)); + aiChooseDirection(actor, VecToAngle(dvec)); if (pTarget->xspr.health == 0) { aiNewState(actor, &batSearch); @@ -295,7 +295,7 @@ static void batMoveForward(DBloodActor* actor) { assert(actor->spr.type >= kDudeBase && actor->spr.type < kDudeMax); DUDEINFO* pDudeInfo = getDudeInfo(actor->spr.type); - auto nAng = deltaangle(actor->spr.angle, DAngle::fromBuild(actor->xspr._goalAng)); + auto nAng = deltaangle(actor->spr.angle, actor->xspr.goalAng); auto nTurnRange = DAngle::fromQ16(pDudeInfo->angSpeed << 3); actor->spr.angle += clamp(nAng, -nTurnRange, nTurnRange); int nAccel = pDudeInfo->frontSpeed << 2; @@ -320,13 +320,13 @@ static void batMoveSwoop(DBloodActor* actor) { assert(actor->spr.type >= kDudeBase && actor->spr.type < kDudeMax); DUDEINFO* pDudeInfo = getDudeInfo(actor->spr.type); - auto nAng = deltaangle(actor->spr.angle, DAngle::fromBuild(actor->xspr._goalAng)); + auto nAng = deltaangle(actor->spr.angle, actor->xspr.goalAng); auto nTurnRange = DAngle::fromQ16(pDudeInfo->angSpeed << 3); actor->spr.angle += clamp(nAng, -nTurnRange, nTurnRange); int nAccel = pDudeInfo->frontSpeed << 2; if (abs(nAng) > DAngle60) { - actor->xspr._goalAng = (actor->int_ang() + 512) & 2047; + actor->xspr.goalAng += DAngle90; return; } auto dvec = actor->xspr.TargetPos.XY() - actor->spr.pos.X; @@ -344,7 +344,7 @@ static void batMoveFly(DBloodActor* actor) { assert(actor->spr.type >= kDudeBase && actor->spr.type < kDudeMax); DUDEINFO* pDudeInfo = getDudeInfo(actor->spr.type); - auto nAng = deltaangle(actor->spr.angle, DAngle::fromBuild(actor->xspr._goalAng)); + auto nAng = deltaangle(actor->spr.angle, actor->xspr.goalAng); auto nTurnRange = DAngle::fromQ16(pDudeInfo->angSpeed << 3); actor->spr.angle += clamp(nAng, -nTurnRange, nTurnRange); int nAccel = pDudeInfo->frontSpeed << 2; diff --git a/source/games/blood/src/aibeast.cpp b/source/games/blood/src/aibeast.cpp index b15bc5402..97fa50c55 100644 --- a/source/games/blood/src/aibeast.cpp +++ b/source/games/blood/src/aibeast.cpp @@ -163,7 +163,7 @@ static void MorphToBeast(DBloodActor* actor) static void beastThinkSearch(DBloodActor* actor) { - aiChooseDirection(actor, actor->xspr._goalAng); + aiChooseDirection(actor, actor->xspr.goalAng); aiThinkTarget(actor); } @@ -175,10 +175,10 @@ static void beastThinkGoto(DBloodActor* actor) auto pXSector = pSector->hasX() ? &pSector->xs() : nullptr; auto dvec = actor->xspr.TargetPos.XY() - actor->spr.pos.XY(); - int nAngle = getangle(dvec); + auto nAngle = VecToAngle(dvec); int nDist = approxDist(dvec); aiChooseDirection(actor, nAngle); - if (nDist < 512 && abs(actor->int_ang() - nAngle) < pDudeInfo->periphery) + if (nDist < 512 && absangle(actor->spr.angle, nAngle) < DAngle::fromBuild(pDudeInfo->periphery)) { if (pXSector && pXSector->Underwater) aiNewState(actor, &beastSwimSearch); @@ -208,7 +208,7 @@ static void beastThinkChase(DBloodActor* actor) int dx = target->int_pos().X - actor->int_pos().X; int dy = target->int_pos().Y - actor->int_pos().Y; - aiChooseDirection(actor, getangle(dx, dy)); + aiChooseDirection(actor, VecToAngle(dx, dy)); auto pSector = actor->sector(); auto pXSector = pSector->hasX() ? &pSector->xs() : nullptr; @@ -325,10 +325,10 @@ static void beastThinkSwimGoto(DBloodActor* actor) assert(actor->spr.type >= kDudeBase && actor->spr.type < kDudeMax); DUDEINFO* pDudeInfo = getDudeInfo(actor->spr.type); auto dvec = actor->xspr.TargetPos.XY() - actor->spr.pos.XY(); - int nAngle = getangle(dvec); + auto nAngle = VecToAngle(dvec); int nDist = approxDist(dvec); aiChooseDirection(actor, nAngle); - if (nDist < 512 && abs(actor->int_ang() - nAngle) < pDudeInfo->periphery) + if (nDist < 512 && absangle(actor->spr.angle, nAngle) < DAngle::fromBuild(pDudeInfo->periphery)) aiNewState(actor, &beastSwimSearch); aiThinkTarget(actor); } @@ -346,7 +346,7 @@ static void beastThinkSwimChase(DBloodActor* actor) auto target = actor->GetTarget(); auto dvec = target->spr.pos.XY() - actor->spr.pos.XY(); - int nAngle = getangle(dvec); + DAngle nAngle = VecToAngle(dvec); int nDist = approxDist(dvec); aiChooseDirection(actor, nAngle); @@ -363,7 +363,7 @@ static void beastThinkSwimChase(DBloodActor* actor) if (nDist <= pDudeInfo->seeDist) { - int nDeltaAngle = getincangle(actor->int_ang(), nAngle); + int nDeltaAngle = getincangle(actor->int_ang(), nAngle.Buildang()); double height = (pDudeInfo->eyeHeight * actor->spr.yrepeat) * REPEAT_SCALE; int top, bottom; GetActorExtents(actor, &top, &bottom); @@ -393,7 +393,7 @@ static void beastMoveForward(DBloodActor* actor) { assert(actor->spr.type >= kDudeBase && actor->spr.type < kDudeMax); DUDEINFO* pDudeInfo = getDudeInfo(actor->spr.type); - auto nAng = deltaangle(actor->spr.angle, DAngle::fromBuild(actor->xspr._goalAng)); + auto nAng = deltaangle(actor->spr.angle, actor->xspr.goalAng); auto nTurnRange = DAngle::fromQ16(pDudeInfo->angSpeed << 3); actor->spr.angle += clamp(nAng, -nTurnRange, nTurnRange); if (abs(nAng) > DAngle60) @@ -410,7 +410,7 @@ static void sub_628A0(DBloodActor* actor) { assert(actor->spr.type >= kDudeBase && actor->spr.type < kDudeMax); DUDEINFO* pDudeInfo = getDudeInfo(actor->spr.type); - auto nAng = deltaangle(actor->spr.angle, DAngle::fromBuild(actor->xspr._goalAng)); + auto nAng = deltaangle(actor->spr.angle, actor->xspr.goalAng); auto nTurnRange = DAngle::fromQ16(pDudeInfo->angSpeed << 3); actor->spr.angle += clamp(nAng, -nTurnRange, nTurnRange); int nAccel = pDudeInfo->frontSpeed << 2; @@ -438,13 +438,13 @@ static void sub_62AE0(DBloodActor* actor) auto target = actor->GetTarget(); int z = actor->int_pos().Z + getDudeInfo(actor->spr.type)->eyeHeight; int z2 = target->int_pos().Z + getDudeInfo(target->spr.type)->eyeHeight; - auto nAng = deltaangle(actor->spr.angle, DAngle::fromBuild(actor->xspr._goalAng)); + auto nAng = deltaangle(actor->spr.angle, actor->xspr.goalAng); auto nTurnRange = DAngle::fromQ16(pDudeInfo->angSpeed << 3); actor->spr.angle += clamp(nAng, -nTurnRange, nTurnRange); int nAccel = pDudeInfo->frontSpeed << 2; if (abs(nAng) > DAngle60) { - actor->xspr._goalAng = (actor->int_ang() + 512) & 2047; + actor->xspr.goalAng += DAngle90; return; } auto dvec = actor->xspr.TargetPos.XY() - actor->spr.pos.XY(); @@ -467,7 +467,7 @@ static void sub_62D7C(DBloodActor* actor) auto target = actor->GetTarget(); int z = actor->int_pos().Z + getDudeInfo(actor->spr.type)->eyeHeight; int z2 = target->int_pos().Z + getDudeInfo(target->spr.type)->eyeHeight; - auto nAng = deltaangle(actor->spr.angle, DAngle::fromBuild(actor->xspr._goalAng)); + auto nAng = deltaangle(actor->spr.angle, actor->xspr.goalAng); auto nTurnRange = DAngle::fromQ16(pDudeInfo->angSpeed << 3); actor->spr.angle += clamp(nAng, -nTurnRange, nTurnRange); int nAccel = pDudeInfo->frontSpeed << 2; diff --git a/source/games/blood/src/aiboneel.cpp b/source/games/blood/src/aiboneel.cpp index ba2ee5dde..8c8dd92dd 100644 --- a/source/games/blood/src/aiboneel.cpp +++ b/source/games/blood/src/aiboneel.cpp @@ -97,7 +97,7 @@ static void eelThinkTarget(DBloodActor* actor) else if (pDudeExtraE->thinkTime >= 10 && pDudeExtraE->active) { pDudeExtraE->thinkTime = 0; - actor->xspr._goalAng += 256; + actor->xspr.goalAng += DAngle45; aiSetTarget(actor, actor->basePoint); aiNewState(actor, &eelTurn); return; @@ -140,7 +140,7 @@ static void eelThinkTarget(DBloodActor* actor) static void eelThinkSearch(DBloodActor* actor) { - aiChooseDirection(actor, actor->xspr._goalAng); + aiChooseDirection(actor, actor->xspr.goalAng); eelThinkTarget(actor); } @@ -149,10 +149,10 @@ static void eelThinkGoto(DBloodActor* actor) assert(actor->spr.type >= kDudeBase && actor->spr.type < kDudeMax); DUDEINFO* pDudeInfo = getDudeInfo(actor->spr.type); auto dvec = actor->xspr.TargetPos.XY() - actor->spr.pos.XY(); - int nAngle = getangle(dvec); + auto nAngle = VecToAngle(dvec); int nDist = approxDist(dvec); aiChooseDirection(actor, nAngle); - if (nDist < 512 && abs(actor->int_ang() - nAngle) < pDudeInfo->periphery) + if (nDist < 512 && absangle(actor->spr.angle, nAngle) < DAngle::fromBuild(pDudeInfo->periphery)) aiNewState(actor, &eelSearch); eelThinkTarget(actor); } @@ -171,7 +171,7 @@ static void eelThinkPonder(DBloodActor* actor) auto dvec = target->spr.pos.XY() - actor->spr.pos.XY(); int nAngle = getangle(dvec); int nDist = approxDist(dvec); - aiChooseDirection(actor, nAngle); + aiChooseDirection(actor, DAngle::fromBuild(nAngle)); if (target->xspr.health == 0) { aiNewState(actor, &eelSearch); @@ -215,7 +215,7 @@ static void eelMoveDodgeUp(DBloodActor* actor) { assert(actor->spr.type >= kDudeBase && actor->spr.type < kDudeMax); DUDEINFO* pDudeInfo = getDudeInfo(actor->spr.type); - auto nAng = deltaangle(actor->spr.angle, DAngle::fromBuild(actor->xspr._goalAng)); + auto nAng = deltaangle(actor->spr.angle, actor->xspr.goalAng); auto nTurnRange = DAngle::fromQ16(pDudeInfo->angSpeed << 3); actor->spr.angle += clamp(nAng, -nTurnRange, nTurnRange); AdjustVelocity(actor, ADJUSTER{ @@ -232,7 +232,7 @@ static void eelMoveDodgeDown(DBloodActor* actor) { assert(actor->spr.type >= kDudeBase && actor->spr.type < kDudeMax); DUDEINFO* pDudeInfo = getDudeInfo(actor->spr.type); - auto nAng = deltaangle(actor->spr.angle, DAngle::fromBuild(actor->xspr._goalAng)); + auto nAng = deltaangle(actor->spr.angle, actor->xspr.goalAng); auto nTurnRange = DAngle::fromQ16(pDudeInfo->angSpeed << 3); actor->spr.angle += clamp(nAng, -nTurnRange, nTurnRange); if (actor->xspr.dodgeDir == 0) @@ -261,7 +261,7 @@ static void eelThinkChase(DBloodActor* actor) auto dvec = target->spr.pos.XY() - actor->spr.pos.XY(); int nAngle = getangle(dvec); int nDist = approxDist(dvec); - aiChooseDirection(actor, nAngle); + aiChooseDirection(actor, DAngle::fromBuild(nAngle)); if (target->xspr.health == 0) { aiNewState(actor, &eelSearch); @@ -307,7 +307,7 @@ static void eelMoveForward(DBloodActor* actor) { assert(actor->spr.type >= kDudeBase && actor->spr.type < kDudeMax); DUDEINFO* pDudeInfo = getDudeInfo(actor->spr.type); - auto nAng = deltaangle(actor->spr.angle, DAngle::fromBuild(actor->xspr._goalAng)); + auto nAng = deltaangle(actor->spr.angle, actor->xspr.goalAng); auto nTurnRange = DAngle::fromQ16(pDudeInfo->angSpeed << 3); actor->spr.angle += clamp(nAng, -nTurnRange, nTurnRange); int nAccel = (pDudeInfo->frontSpeed - (((4 - gGameOptions.nDifficulty) << 26) / 120) / 120) << 2; @@ -332,7 +332,7 @@ static void eelMoveSwoop(DBloodActor* actor) { assert(actor->spr.type >= kDudeBase && actor->spr.type < kDudeMax); DUDEINFO* pDudeInfo = getDudeInfo(actor->spr.type); - auto nAng = deltaangle(actor->spr.angle, DAngle::fromBuild(actor->xspr._goalAng)); + auto nAng = deltaangle(actor->spr.angle, actor->xspr.goalAng); auto nTurnRange = DAngle::fromQ16(pDudeInfo->angSpeed << 3); actor->spr.angle += clamp(nAng, -nTurnRange, nTurnRange); int nAccel = (pDudeInfo->frontSpeed - (((4 - gGameOptions.nDifficulty) << 26) / 120) / 120) << 2; @@ -353,7 +353,7 @@ static void eelMoveAscend(DBloodActor* actor) { assert(actor->spr.type >= kDudeBase && actor->spr.type < kDudeMax); DUDEINFO* pDudeInfo = getDudeInfo(actor->spr.type); - auto nAng = deltaangle(actor->spr.angle, DAngle::fromBuild(actor->xspr._goalAng)); + auto nAng = deltaangle(actor->spr.angle, actor->xspr.goalAng); auto nTurnRange = DAngle::fromQ16(pDudeInfo->angSpeed << 3); actor->spr.angle += clamp(nAng, -nTurnRange, nTurnRange); int nAccel = (pDudeInfo->frontSpeed - (((4 - gGameOptions.nDifficulty) << 26) / 120) / 120) << 2; diff --git a/source/games/blood/src/aiburn.cpp b/source/games/blood/src/aiburn.cpp index c1929fb55..326295a16 100644 --- a/source/games/blood/src/aiburn.cpp +++ b/source/games/blood/src/aiburn.cpp @@ -76,7 +76,7 @@ void BurnSeqCallback(int, DBloodActor*) static void burnThinkSearch(DBloodActor* actor) { - aiChooseDirection(actor, actor->xspr._goalAng); + aiChooseDirection(actor, actor->xspr.goalAng); aiThinkTarget(actor); } @@ -87,7 +87,7 @@ static void burnThinkGoto(DBloodActor* actor) auto dvec = actor->xspr.TargetPos.XY() - actor->spr.pos.XY(); int nAngle = getangle(dvec); int nDist = approxDist(dvec); - aiChooseDirection(actor, nAngle); + aiChooseDirection(actor, DAngle::fromBuild(nAngle)); if (nDist < 512 && abs(actor->int_ang() - nAngle) < pDudeInfo->periphery) { switch (actor->spr.type) @@ -160,7 +160,7 @@ static void burnThinkChase(DBloodActor* actor) int nAngle = getangle(dvec); int nDist = approxDist(dvec); - aiChooseDirection(actor, nAngle); + aiChooseDirection(actor, DAngle::fromBuild(nAngle)); if (target->xspr.health == 0) { switch (actor->spr.type) diff --git a/source/games/blood/src/aicaleb.cpp b/source/games/blood/src/aicaleb.cpp index 5c2e4dd2d..aef0dfe98 100644 --- a/source/games/blood/src/aicaleb.cpp +++ b/source/games/blood/src/aicaleb.cpp @@ -82,7 +82,7 @@ void SeqAttackCallback(int, DBloodActor* actor) static void calebThinkSearch(DBloodActor* actor) { - aiChooseDirection(actor, actor->xspr._goalAng); + aiChooseDirection(actor, actor->xspr.goalAng); aiThinkTarget(actor); } @@ -97,7 +97,7 @@ static void calebThinkGoto(DBloodActor* actor) auto dvec = actor->xspr.TargetPos.XY() - actor->spr.pos.XY(); int nAngle = getangle(dvec); int nDist = approxDist(dvec); - aiChooseDirection(actor, nAngle); + aiChooseDirection(actor, DAngle::fromBuild(nAngle)); if (nDist < 512 && abs(actor->int_ang() - nAngle) < pDudeInfo->periphery) { if (pXSector && pXSector->Underwater) @@ -128,7 +128,7 @@ static void calebThinkChase(DBloodActor* actor) auto dvec = target->spr.pos.XY() - actor->spr.pos.XY(); int nAngle = getangle(dvec); int nDist = approxDist(dvec); - aiChooseDirection(actor, nAngle); + aiChooseDirection(actor, DAngle::fromBuild(nAngle)); if (target->xspr.health == 0) { if (pXSector && pXSector->Underwater) @@ -217,7 +217,7 @@ static void calebThinkSwimGoto(DBloodActor* actor) auto dvec = actor->xspr.TargetPos.XY() - actor->spr.pos.XY(); int nAngle = getangle(dvec); int nDist = approxDist(dvec); - aiChooseDirection(actor, nAngle); + aiChooseDirection(actor, DAngle::fromBuild(nAngle)); if (nDist < 512 && abs(actor->int_ang() - nAngle) < pDudeInfo->periphery) aiNewState(actor, &tinycalebSwimSearch); aiThinkTarget(actor); @@ -237,7 +237,7 @@ static void calebThinkSwimChase(DBloodActor* actor) auto dvec = target->spr.pos.XY() - actor->spr.pos.XY(); int nAngle = getangle(dvec); int nDist = approxDist(dvec); - aiChooseDirection(actor, nAngle); + aiChooseDirection(actor, DAngle::fromBuild(nAngle)); if (target->xspr.health == 0) { aiNewState(actor, &tinycalebSwimSearch); @@ -278,7 +278,7 @@ static void sub_65D04(DBloodActor* actor) { assert(actor->spr.type >= kDudeBase && actor->spr.type < kDudeMax); DUDEINFO* pDudeInfo = getDudeInfo(actor->spr.type); - auto nAng = deltaangle(actor->spr.angle, DAngle::fromBuild(actor->xspr._goalAng)); + auto nAng = deltaangle(actor->spr.angle, actor->xspr.goalAng); auto nTurnRange = DAngle::fromQ16(pDudeInfo->angSpeed << 3); actor->spr.angle += clamp(nAng, -nTurnRange, nTurnRange); int nAccel = pDudeInfo->frontSpeed << 2; @@ -308,13 +308,13 @@ static void sub_65F44(DBloodActor* actor) auto target = actor->GetTarget(); int z = actor->int_pos().Z + getDudeInfo(actor->spr.type)->eyeHeight; int z2 = target->int_pos().Z + getDudeInfo(target->spr.type)->eyeHeight; - auto nAng = deltaangle(actor->spr.angle, DAngle::fromBuild(actor->xspr._goalAng)); + auto nAng = deltaangle(actor->spr.angle, actor->xspr.goalAng); auto nTurnRange = DAngle::fromQ16(pDudeInfo->angSpeed << 3); actor->spr.angle += clamp(nAng, -nTurnRange, nTurnRange); int nAccel = pDudeInfo->frontSpeed << 2; if (abs(nAng) > DAngle60) { - actor->xspr._goalAng = (actor->int_ang() + 512) & 2047; + actor->xspr.goalAng += DAngle90; return; } auto dvec = actor->xspr.TargetPos.XY() - actor->spr.pos.XY(); @@ -338,7 +338,7 @@ static void sub_661E0(DBloodActor* actor) auto target = actor->GetTarget(); int z = actor->int_pos().Z + getDudeInfo(actor->spr.type)->eyeHeight; int z2 = target->int_pos().Z + getDudeInfo(target->spr.type)->eyeHeight; - auto nAng = deltaangle(actor->spr.angle, DAngle::fromBuild(actor->xspr._goalAng)); + auto nAng = deltaangle(actor->spr.angle, actor->xspr.goalAng); auto nTurnRange = DAngle::fromQ16(pDudeInfo->angSpeed << 3); actor->spr.angle += clamp(nAng, -nTurnRange, nTurnRange); int nAccel = pDudeInfo->frontSpeed << 2; diff --git a/source/games/blood/src/aicerber.cpp b/source/games/blood/src/aicerber.cpp index 786dec8d6..5d11c3687 100644 --- a/source/games/blood/src/aicerber.cpp +++ b/source/games/blood/src/aicerber.cpp @@ -227,7 +227,7 @@ void cerberusBurnSeqCallback2(int, DBloodActor* actor) static void cerberusThinkSearch(DBloodActor* actor) { - aiChooseDirection(actor, actor->xspr._goalAng); + aiChooseDirection(actor, actor->xspr.goalAng); aiThinkTarget(actor); } @@ -243,7 +243,7 @@ static void cerberusThinkTarget(DBloodActor* actor) pDudeExtraE->thinkTime++; else if (pDudeExtraE->thinkTime >= 10 && pDudeExtraE->active) { - actor->xspr._goalAng += 256; + actor->xspr.goalAng += DAngle45; aiSetTarget(actor, actor->basePoint); if (actor->spr.type == kDudeCerberusTwoHead) aiNewState(actor, &cerberus139890); @@ -297,7 +297,7 @@ static void cerberusThinkGoto(DBloodActor* actor) auto dvec = actor->xspr.TargetPos.XY() - actor->spr.pos.XY(); int nAngle = getangle(dvec); int nDist = approxDist(dvec); - aiChooseDirection(actor, nAngle); + aiChooseDirection(actor, DAngle::fromBuild(nAngle)); if (nDist < 512 && abs(actor->int_ang() - nAngle) < pDudeInfo->periphery) { switch (actor->spr.type) { @@ -340,7 +340,7 @@ static void cerberusThinkChase(DBloodActor* actor) auto dvec = target->spr.pos.XY() - actor->spr.pos.XY(); int nAngle = getangle(dvec); int nDist = approxDist(dvec); - aiChooseDirection(actor, nAngle); + aiChooseDirection(actor, DAngle::fromBuild(nAngle)); if (target->xspr.health == 0) { switch (actor->spr.type) { diff --git a/source/games/blood/src/aicult.cpp b/source/games/blood/src/aicult.cpp index b5b0ca257..66fb45e62 100644 --- a/source/games/blood/src/aicult.cpp +++ b/source/games/blood/src/aicult.cpp @@ -186,7 +186,7 @@ static bool TargetNearExplosion(sectortype* sector) static void cultThinkSearch(DBloodActor* actor) { - aiChooseDirection(actor, actor->xspr._goalAng); + aiChooseDirection(actor, actor->xspr.goalAng); aiLookForTarget(actor); } @@ -197,7 +197,7 @@ static void cultThinkGoto(DBloodActor* actor) auto dvec = actor->xspr.TargetPos.XY() - actor->spr.pos.XY(); int nAngle = getangle(dvec); int nDist = approxDist(dvec); - aiChooseDirection(actor, nAngle); + aiChooseDirection(actor, DAngle::fromBuild(nAngle)); if (nDist < 5120 && abs(actor->int_ang() - nAngle) < pDudeInfo->periphery) { switch (actor->xspr.medium) @@ -236,7 +236,7 @@ static void cultThinkChase(DBloodActor* actor) int dx = target->int_pos().X - actor->int_pos().X; int dy = target->int_pos().Y - actor->int_pos().Y; - aiChooseDirection(actor, getangle(dx, dy)); + aiChooseDirection(actor, VecToAngle(dx, dy)); if (target->xspr.health == 0) { switch (actor->xspr.medium) diff --git a/source/games/blood/src/aigarg.cpp b/source/games/blood/src/aigarg.cpp index 4069c7ee0..154fd76d6 100644 --- a/source/games/blood/src/aigarg.cpp +++ b/source/games/blood/src/aigarg.cpp @@ -206,7 +206,7 @@ static void gargThinkTarget(DBloodActor* actor) pDudeExtraE->thinkTime++; else if (pDudeExtraE->thinkTime >= 10 && pDudeExtraE->active) { - actor->xspr._goalAng += 256; + actor->xspr.goalAng += DAngle45; aiSetTarget(actor, actor->basePoint); aiNewState(actor, &gargoyleTurn); return; @@ -249,7 +249,7 @@ static void gargThinkTarget(DBloodActor* actor) static void gargThinkSearch(DBloodActor* actor) { - aiChooseDirection(actor, actor->xspr._goalAng); + aiChooseDirection(actor, actor->xspr.goalAng); aiLookForTarget(actor); } @@ -263,7 +263,7 @@ static void gargThinkGoto(DBloodActor* actor) auto dvec = actor->xspr.TargetPos.XY() - actor->spr.pos.XY(); int nAngle = getangle(dvec); int nDist = approxDist(dvec); - aiChooseDirection(actor, nAngle); + aiChooseDirection(actor, DAngle::fromBuild(nAngle)); if (nDist < 512 && abs(actor->int_ang() - nAngle) < pDudeInfo->periphery) aiNewState(actor, &gargoyleFSearch); aiThinkTarget(actor); @@ -276,7 +276,7 @@ static void gargMoveDodgeUp(DBloodActor* actor) return; } DUDEINFO* pDudeInfo = getDudeInfo(actor->spr.type); - auto nAng = deltaangle(actor->spr.angle, DAngle::fromBuild(actor->xspr._goalAng)); + auto nAng = deltaangle(actor->spr.angle, actor->xspr.goalAng); auto nTurnRange = DAngle::fromQ16(pDudeInfo->angSpeed << 3); actor->spr.angle += clamp(nAng, -nTurnRange, nTurnRange); AdjustVelocity(actor, ADJUSTER{ @@ -296,7 +296,7 @@ static void gargMoveDodgeDown(DBloodActor* actor) return; } DUDEINFO* pDudeInfo = getDudeInfo(actor->spr.type); - auto nAng = deltaangle(actor->spr.angle, DAngle::fromBuild(actor->xspr._goalAng)); + auto nAng = deltaangle(actor->spr.angle, actor->xspr.goalAng); auto nTurnRange = DAngle::fromQ16(pDudeInfo->angSpeed << 3); actor->spr.angle += clamp(nAng, -nTurnRange, nTurnRange); if (actor->xspr.dodgeDir == 0) @@ -328,7 +328,7 @@ static void gargThinkChase(DBloodActor* actor) int dx = target->int_pos().X - actor->int_pos().X; int dy = target->int_pos().Y - actor->int_pos().Y; - aiChooseDirection(actor, getangle(dx, dy)); + aiChooseDirection(actor, VecToAngle(dx, dy)); if (target->xspr.health == 0) { aiNewState(actor, &gargoyleFSearch); @@ -508,7 +508,7 @@ static void gargMoveForward(DBloodActor* actor) return; } DUDEINFO* pDudeInfo = getDudeInfo(actor->spr.type); - auto nAng = deltaangle(actor->spr.angle, DAngle::fromBuild(actor->xspr._goalAng)); + auto nAng = deltaangle(actor->spr.angle, actor->xspr.goalAng); auto nTurnRange = DAngle::fromQ16(pDudeInfo->angSpeed << 3); actor->spr.angle += clamp(nAng, -nTurnRange, nTurnRange); int nAccel = pDudeInfo->frontSpeed << 2; @@ -536,13 +536,13 @@ static void gargMoveSlow(DBloodActor* actor) return; } DUDEINFO* pDudeInfo = getDudeInfo(actor->spr.type); - auto nAng = deltaangle(actor->spr.angle, DAngle::fromBuild(actor->xspr._goalAng)); + auto nAng = deltaangle(actor->spr.angle, actor->xspr.goalAng); auto nTurnRange = DAngle::fromQ16(pDudeInfo->angSpeed << 3); actor->spr.angle += clamp(nAng, -nTurnRange, nTurnRange); int nAccel = pDudeInfo->frontSpeed << 2; if (abs(nAng) > DAngle60) { - actor->xspr._goalAng = (actor->int_ang() + 512) & 2047; + actor->xspr.goalAng += DAngle90; return; } auto dvec = actor->xspr.TargetPos.XY() - actor->spr.pos.XY(); @@ -571,13 +571,13 @@ static void gargMoveSwoop(DBloodActor* actor) return; } DUDEINFO* pDudeInfo = getDudeInfo(actor->spr.type); - auto nAng = deltaangle(actor->spr.angle, DAngle::fromBuild(actor->xspr._goalAng)); + auto nAng = deltaangle(actor->spr.angle, actor->xspr.goalAng); auto nTurnRange = DAngle::fromQ16(pDudeInfo->angSpeed << 3); actor->spr.angle += clamp(nAng, -nTurnRange, nTurnRange); int nAccel = pDudeInfo->frontSpeed << 2; if (abs(nAng) > DAngle60) { - actor->xspr._goalAng = (actor->int_ang() + 512) & 2047; + actor->xspr.goalAng += DAngle90; return; } auto dvec = actor->xspr.TargetPos.XY() - actor->spr.pos.XY(); @@ -606,7 +606,7 @@ static void gargMoveFly(DBloodActor* actor) return; } DUDEINFO* pDudeInfo = getDudeInfo(actor->spr.type); - auto nAng = deltaangle(actor->spr.angle, DAngle::fromBuild(actor->xspr._goalAng)); + auto nAng = deltaangle(actor->spr.angle, actor->xspr.goalAng); auto nTurnRange = DAngle::fromQ16(pDudeInfo->angSpeed << 3); actor->spr.angle += clamp(nAng, -nTurnRange, nTurnRange); int nAccel = pDudeInfo->frontSpeed << 2; diff --git a/source/games/blood/src/aighost.cpp b/source/games/blood/src/aighost.cpp index f44153e14..05f722356 100644 --- a/source/games/blood/src/aighost.cpp +++ b/source/games/blood/src/aighost.cpp @@ -186,7 +186,7 @@ static void ghostThinkTarget(DBloodActor* actor) pDudeExtraE->thinkTime++; else if (pDudeExtraE->thinkTime >= 10 && pDudeExtraE->active) { - actor->xspr._goalAng += 256; + actor->xspr.goalAng += DAngle45; aiSetTarget(actor, actor->basePoint); aiNewState(actor, &ghostTurn); return; @@ -228,7 +228,7 @@ static void ghostThinkTarget(DBloodActor* actor) static void ghostThinkSearch(DBloodActor* actor) { - aiChooseDirection(actor, actor->xspr._goalAng); + aiChooseDirection(actor, actor->xspr.goalAng); aiThinkTarget(actor); } @@ -242,7 +242,7 @@ static void ghostThinkGoto(DBloodActor* actor) auto dvec = actor->xspr.TargetPos.XY() - actor->spr.pos.XY(); int nAngle = getangle(dvec); int nDist = approxDist(dvec); - aiChooseDirection(actor, nAngle); + aiChooseDirection(actor, DAngle::fromBuild(nAngle)); if (nDist < 512 && abs(actor->int_ang() - nAngle) < pDudeInfo->periphery) aiNewState(actor, &ghostSearch); aiThinkTarget(actor); @@ -255,7 +255,7 @@ static void ghostMoveDodgeUp(DBloodActor* actor) return; } DUDEINFO* pDudeInfo = getDudeInfo(actor->spr.type); - auto nAng = deltaangle(actor->spr.angle, DAngle::fromBuild(actor->xspr._goalAng)); + auto nAng = deltaangle(actor->spr.angle, actor->xspr.goalAng); auto nTurnRange = DAngle::fromQ16(pDudeInfo->angSpeed << 3); actor->spr.angle += clamp(nAng, -nTurnRange, nTurnRange); AdjustVelocity(actor, ADJUSTER{ @@ -275,7 +275,7 @@ static void ghostMoveDodgeDown(DBloodActor* actor) return; } DUDEINFO* pDudeInfo = getDudeInfo(actor->spr.type); - auto nAng = deltaangle(actor->spr.angle, DAngle::fromBuild(actor->xspr._goalAng)); + auto nAng = deltaangle(actor->spr.angle, actor->xspr.goalAng); auto nTurnRange = DAngle::fromQ16(pDudeInfo->angSpeed << 3); actor->spr.angle += clamp(nAng, -nTurnRange, nTurnRange); if (actor->xspr.dodgeDir == 0) @@ -306,7 +306,7 @@ static void ghostThinkChase(DBloodActor* actor) int dx = target->int_pos().X - actor->int_pos().X; int dy = target->int_pos().Y - actor->int_pos().Y; - aiChooseDirection(actor, getangle(dx, dy)); + aiChooseDirection(actor, VecToAngle(dx, dy)); if (target->xspr.health == 0) { aiNewState(actor, &ghostSearch); @@ -403,7 +403,7 @@ static void ghostMoveForward(DBloodActor* actor) return; } DUDEINFO* pDudeInfo = getDudeInfo(actor->spr.type); - auto nAng = deltaangle(actor->spr.angle, DAngle::fromBuild(actor->xspr._goalAng)); + auto nAng = deltaangle(actor->spr.angle, actor->xspr.goalAng); auto nTurnRange = DAngle::fromQ16(pDudeInfo->angSpeed << 3); actor->spr.angle += clamp(nAng, -nTurnRange, nTurnRange); int nAccel = pDudeInfo->frontSpeed << 2; @@ -430,13 +430,13 @@ static void ghostMoveSlow(DBloodActor* actor) return; } DUDEINFO* pDudeInfo = getDudeInfo(actor->spr.type); - auto nAng = deltaangle(actor->spr.angle, DAngle::fromBuild(actor->xspr._goalAng)); + auto nAng = deltaangle(actor->spr.angle, actor->xspr.goalAng); auto nTurnRange = DAngle::fromQ16(pDudeInfo->angSpeed << 3); actor->spr.angle += clamp(nAng, -nTurnRange, nTurnRange); int nAccel = pDudeInfo->frontSpeed << 2; if (abs(nAng) > DAngle60) { - actor->xspr._goalAng = (actor->int_ang() + 512) & 2047; + actor->xspr.goalAng += DAngle90; return; } auto dvec = actor->xspr.TargetPos.XY() - actor->spr.pos.XY(); @@ -461,13 +461,13 @@ static void ghostMoveSwoop(DBloodActor* actor) return; } DUDEINFO* pDudeInfo = getDudeInfo(actor->spr.type); - auto nAng = deltaangle(actor->spr.angle, DAngle::fromBuild(actor->xspr._goalAng)); + auto nAng = deltaangle(actor->spr.angle, actor->xspr.goalAng); auto nTurnRange = DAngle::fromQ16(pDudeInfo->angSpeed << 3); actor->spr.angle += clamp(nAng, -nTurnRange, nTurnRange); int nAccel = pDudeInfo->frontSpeed << 2; if (abs(nAng) > DAngle60) { - actor->xspr._goalAng = (actor->int_ang() + 512) & 2047; + actor->xspr.goalAng += DAngle90; return; } auto dvec = actor->xspr.TargetPos.XY() - actor->spr.pos.XY(); @@ -491,7 +491,7 @@ static void ghostMoveFly(DBloodActor* actor) return; } DUDEINFO* pDudeInfo = getDudeInfo(actor->spr.type); - auto nAng = deltaangle(actor->spr.angle, DAngle::fromBuild(actor->xspr._goalAng)); + auto nAng = deltaangle(actor->spr.angle, actor->xspr.goalAng); auto nTurnRange = DAngle::fromQ16(pDudeInfo->angSpeed << 3); actor->spr.angle += clamp(nAng, -nTurnRange, nTurnRange); int nAccel = pDudeInfo->frontSpeed << 2; diff --git a/source/games/blood/src/aigilbst.cpp b/source/games/blood/src/aigilbst.cpp index 7a63ccd1d..8a973b021 100644 --- a/source/games/blood/src/aigilbst.cpp +++ b/source/games/blood/src/aigilbst.cpp @@ -73,7 +73,7 @@ void GillBiteSeqCallback(int, DBloodActor* actor) static void gillThinkSearch(DBloodActor* actor) { - aiChooseDirection(actor, actor->xspr._goalAng); + aiChooseDirection(actor, actor->xspr.goalAng); aiThinkTarget(actor); } @@ -88,7 +88,7 @@ static void gillThinkGoto(DBloodActor* actor) auto dvec = actor->xspr.TargetPos.XY() - actor->spr.pos.XY(); int nAngle = getangle(dvec); int nDist = approxDist(dvec); - aiChooseDirection(actor, nAngle); + aiChooseDirection(actor, DAngle::fromBuild(nAngle)); if (nDist < 512 && abs(actor->int_ang() - nAngle) < pDudeInfo->periphery) { if (pXSector && pXSector->Underwater) @@ -118,7 +118,7 @@ static void gillThinkChase(DBloodActor* actor) auto target = actor->GetTarget(); int dx = target->int_pos().X - actor->int_pos().X; int dy = target->int_pos().Y - actor->int_pos().Y; - aiChooseDirection(actor, getangle(dx, dy)); + aiChooseDirection(actor, VecToAngle(dx, dy)); if (actor->xspr.health == 0) { if (pXSector && pXSector->Underwater) @@ -201,7 +201,7 @@ static void gillThinkSwimGoto(DBloodActor* actor) auto dvec = actor->xspr.TargetPos.XY() - actor->spr.pos.XY(); int nAngle = getangle(dvec); int nDist = approxDist(dvec); - aiChooseDirection(actor, nAngle); + aiChooseDirection(actor, DAngle::fromBuild(nAngle)); if (nDist < 512 && abs(actor->int_ang() - nAngle) < pDudeInfo->periphery) aiNewState(actor, &gillBeastSwimSearch); aiThinkTarget(actor); @@ -221,7 +221,7 @@ static void gillThinkSwimChase(DBloodActor* actor) auto dvec = target->spr.pos.XY() - actor->spr.pos.XY(); int nAngle = getangle(dvec); int nDist = approxDist(dvec); - aiChooseDirection(actor, nAngle); + aiChooseDirection(actor, DAngle::fromBuild(nAngle)); if (actor->xspr.health == 0) { aiNewState(actor, &gillBeastSwimSearch); @@ -265,7 +265,7 @@ static void sub_6CB00(DBloodActor* actor) { assert(actor->spr.type >= kDudeBase && actor->spr.type < kDudeMax); DUDEINFO* pDudeInfo = getDudeInfo(actor->spr.type); - auto nAng = deltaangle(actor->spr.angle, DAngle::fromBuild(actor->xspr._goalAng)); + auto nAng = deltaangle(actor->spr.angle, actor->xspr.goalAng); auto nTurnRange = DAngle::fromQ16(pDudeInfo->angSpeed << 3); actor->spr.angle += clamp(nAng, -nTurnRange, nTurnRange); int nAccel = (pDudeInfo->frontSpeed - (((4 - gGameOptions.nDifficulty) << 27) / 120) / 120) << 2; @@ -294,13 +294,13 @@ static void sub_6CD74(DBloodActor* actor) auto target = actor->GetTarget(); int z = actor->int_pos().Z + getDudeInfo(actor->spr.type)->eyeHeight; int z2 = target->int_pos().Z + getDudeInfo(target->spr.type)->eyeHeight; - auto nAng = deltaangle(actor->spr.angle, DAngle::fromBuild(actor->xspr._goalAng)); + auto nAng = deltaangle(actor->spr.angle, actor->xspr.goalAng); auto nTurnRange = DAngle::fromQ16(pDudeInfo->angSpeed << 3); actor->spr.angle += clamp(nAng, -nTurnRange, nTurnRange); int nAccel = (pDudeInfo->frontSpeed - (((4 - gGameOptions.nDifficulty) << 27) / 120) / 120) << 2; if (abs(nAng) > DAngle60) { - actor->xspr._goalAng = (actor->int_ang() + 512) & 2047; + actor->xspr.goalAng += DAngle90; return; } auto dvec = actor->xspr.TargetPos.XY() - actor->spr.pos.XY(); @@ -323,7 +323,7 @@ static void sub_6D03C(DBloodActor* actor) auto target = actor->GetTarget(); int z = actor->int_pos().Z + getDudeInfo(actor->spr.type)->eyeHeight; int z2 = target->int_pos().Z + getDudeInfo(target->spr.type)->eyeHeight; - auto nAng = deltaangle(actor->spr.angle, DAngle::fromBuild(actor->xspr._goalAng)); + auto nAng = deltaangle(actor->spr.angle, actor->xspr.goalAng); auto nTurnRange = DAngle::fromQ16(pDudeInfo->angSpeed << 3); actor->spr.angle += clamp(nAng, -nTurnRange, nTurnRange); int nAccel = (pDudeInfo->frontSpeed - (((4 - gGameOptions.nDifficulty) << 27) / 120) / 120) << 2; diff --git a/source/games/blood/src/aihand.cpp b/source/games/blood/src/aihand.cpp index b13a68cfa..7a85e9619 100644 --- a/source/games/blood/src/aihand.cpp +++ b/source/games/blood/src/aihand.cpp @@ -58,7 +58,7 @@ void HandJumpSeqCallback(int, DBloodActor* actor) static void handThinkSearch(DBloodActor* actor) { - aiChooseDirection(actor, actor->xspr._goalAng); + aiChooseDirection(actor, actor->xspr.goalAng); aiThinkTarget(actor); } @@ -69,7 +69,7 @@ static void handThinkGoto(DBloodActor* actor) auto dvec = actor->xspr.TargetPos.XY() - actor->spr.pos.XY(); int nAngle = getangle(dvec); int nDist = approxDist(dvec); - aiChooseDirection(actor, nAngle); + aiChooseDirection(actor, DAngle::fromBuild(nAngle)); if (nDist < 512 && abs(actor->int_ang() - nAngle) < pDudeInfo->periphery) aiNewState(actor, &handSearch); aiThinkTarget(actor); @@ -90,7 +90,7 @@ static void handThinkChase(DBloodActor* actor) auto dvec = target->spr.pos.XY() - actor->spr.pos.XY(); int nAngle = getangle(dvec); int nDist = approxDist(dvec); - aiChooseDirection(actor, nAngle); + aiChooseDirection(actor, DAngle::fromBuild(nAngle)); if (target->xspr.health == 0) { aiNewState(actor, &handSearch); diff --git a/source/games/blood/src/aihound.cpp b/source/games/blood/src/aihound.cpp index fc85628cd..e799a840e 100644 --- a/source/games/blood/src/aihound.cpp +++ b/source/games/blood/src/aihound.cpp @@ -69,7 +69,7 @@ void houndBurnSeqCallback(int, DBloodActor* actor) static void houndThinkSearch(DBloodActor* actor) { - aiChooseDirection(actor, actor->xspr._goalAng); + aiChooseDirection(actor, actor->xspr.goalAng); aiThinkTarget(actor); } @@ -84,7 +84,7 @@ static void houndThinkGoto(DBloodActor* actor) auto dvec = actor->xspr.TargetPos.XY() - actor->spr.pos.XY(); int nAngle = getangle(dvec); int nDist = approxDist(dvec); - aiChooseDirection(actor, nAngle); + aiChooseDirection(actor, DAngle::fromBuild(nAngle)); if (nDist < 512 && abs(actor->int_ang() - nAngle) < pDudeInfo->periphery) aiNewState(actor, &houndSearch); aiThinkTarget(actor); @@ -107,7 +107,7 @@ static void houndThinkChase(DBloodActor* actor) auto dvec = target->spr.pos.XY() - actor->spr.pos.XY(); int nAngle = getangle(dvec); int nDist = approxDist(dvec); - aiChooseDirection(actor, nAngle); + aiChooseDirection(actor, DAngle::fromBuild(nAngle)); if (target->xspr.health == 0) { aiNewState(actor, &houndSearch); diff --git a/source/games/blood/src/aiinnoc.cpp b/source/games/blood/src/aiinnoc.cpp index 5104e2584..ed7abf94f 100644 --- a/source/games/blood/src/aiinnoc.cpp +++ b/source/games/blood/src/aiinnoc.cpp @@ -42,7 +42,7 @@ AISTATE innocentGoto = { kAiStateMove, 6, -1, 600, NULL, aiMoveForward, innocThi static void innocThinkSearch(DBloodActor* actor) { - aiChooseDirection(actor, actor->xspr._goalAng); + aiChooseDirection(actor, actor->xspr.goalAng); aiThinkTarget(actor); } @@ -53,7 +53,7 @@ static void innocThinkGoto(DBloodActor* actor) auto dvec = actor->xspr.TargetPos.XY() - actor->spr.pos.XY(); int nAngle = getangle(dvec); int nDist = approxDist(dvec); - aiChooseDirection(actor, nAngle); + aiChooseDirection(actor, DAngle::fromBuild(nAngle)); if (nDist < 512 && abs(actor->int_ang() - nAngle) < pDudeInfo->periphery) aiNewState(actor, &innocentSearch); aiThinkTarget(actor); @@ -74,7 +74,7 @@ static void innocThinkChase(DBloodActor* actor) auto dvec = target->spr.pos.XY() - actor->spr.pos.XY(); int nAngle = getangle(dvec); int nDist = approxDist(dvec); - aiChooseDirection(actor, nAngle); + aiChooseDirection(actor, DAngle::fromBuild(nAngle)); if (target->xspr.health == 0) { aiNewState(actor, &innocentSearch); diff --git a/source/games/blood/src/aipod.cpp b/source/games/blood/src/aipod.cpp index 2faf5e9c0..b238233a0 100644 --- a/source/games/blood/src/aipod.cpp +++ b/source/games/blood/src/aipod.cpp @@ -127,7 +127,7 @@ void sub_70284(int, DBloodActor* actor) static void aiPodSearch(DBloodActor* actor) { - aiChooseDirection(actor, actor->xspr._goalAng); + aiChooseDirection(actor, actor->xspr.goalAng); aiThinkTarget(actor); } @@ -142,7 +142,7 @@ static void aiPodMove(DBloodActor* actor) auto dvec = actor->xspr.TargetPos.XY() - actor->spr.pos.XY(); int nAngle = getangle(dvec); int nDist = approxDist(dvec); - aiChooseDirection(actor, nAngle); + aiChooseDirection(actor, DAngle::fromBuild(nAngle)); if (nDist < 512 && abs(actor->int_ang() - nAngle) < pDudeInfo->periphery) { switch (actor->spr.type) { case kDudePodGreen: @@ -183,7 +183,7 @@ static void aiPodChase(DBloodActor* actor) auto dvec = target->spr.pos.XY() - actor->spr.pos.XY(); int nAngle = getangle(dvec); int nDist = approxDist(dvec); - aiChooseDirection(actor, nAngle); + aiChooseDirection(actor, DAngle::fromBuild(nAngle)); if (target->xspr.health == 0) { switch (actor->spr.type) { diff --git a/source/games/blood/src/airat.cpp b/source/games/blood/src/airat.cpp index 4845d0118..63eb7e169 100644 --- a/source/games/blood/src/airat.cpp +++ b/source/games/blood/src/airat.cpp @@ -54,7 +54,7 @@ void ratBiteSeqCallback(int, DBloodActor* actor) static void ratThinkSearch(DBloodActor* actor) { - aiChooseDirection(actor, actor->xspr._goalAng); + aiChooseDirection(actor, actor->xspr.goalAng); aiThinkTarget(actor); } @@ -65,7 +65,7 @@ static void ratThinkGoto(DBloodActor* actor) auto dvec = actor->xspr.TargetPos.XY() - actor->spr.pos.XY(); int nAngle = getangle(dvec); int nDist = approxDist(dvec); - aiChooseDirection(actor, nAngle); + aiChooseDirection(actor, DAngle::fromBuild(nAngle)); if (nDist < 512 && abs(actor->int_ang() - nAngle) < pDudeInfo->periphery) aiNewState(actor, &ratSearch); aiThinkTarget(actor); @@ -85,7 +85,7 @@ static void ratThinkChase(DBloodActor* actor) auto dvec = target->spr.pos.XY() - actor->spr.pos.XY(); int nAngle = getangle(dvec); int nDist = approxDist(dvec); - aiChooseDirection(actor, nAngle); + aiChooseDirection(actor, DAngle::fromBuild(nAngle)); if (target->xspr.health == 0) { aiNewState(actor, &ratSearch); diff --git a/source/games/blood/src/aispid.cpp b/source/games/blood/src/aispid.cpp index 679610088..7cf6fd312 100644 --- a/source/games/blood/src/aispid.cpp +++ b/source/games/blood/src/aispid.cpp @@ -162,7 +162,7 @@ void SpidBirthSeqCallback(int, DBloodActor* actor) static void spidThinkSearch(DBloodActor* actor) { - aiChooseDirection(actor, actor->xspr._goalAng); + aiChooseDirection(actor, actor->xspr.goalAng); aiThinkTarget(actor); } @@ -173,7 +173,7 @@ static void spidThinkGoto(DBloodActor* actor) auto dvec = actor->xspr.TargetPos.XY() - actor->spr.pos.XY(); int nAngle = getangle(dvec); int nDist = approxDist(dvec); - aiChooseDirection(actor, nAngle); + aiChooseDirection(actor, DAngle::fromBuild(nAngle)); if (nDist < 512 && abs(actor->int_ang() - nAngle) < pDudeInfo->periphery) aiNewState(actor, &spidSearch); aiThinkTarget(actor); @@ -193,7 +193,7 @@ static void spidThinkChase(DBloodActor* actor) auto dvec = target->spr.pos.XY() - actor->spr.pos.XY(); int nAngle = getangle(dvec); int nDist = approxDist(dvec); - aiChooseDirection(actor, nAngle); + aiChooseDirection(actor, DAngle::fromBuild(nAngle)); if (target->xspr.health == 0) { aiNewState(actor, &spidSearch); diff --git a/source/games/blood/src/aitchern.cpp b/source/games/blood/src/aitchern.cpp index db4a88573..fa2ed036b 100644 --- a/source/games/blood/src/aitchern.cpp +++ b/source/games/blood/src/aitchern.cpp @@ -197,7 +197,7 @@ void sub_720AC(int, DBloodActor* actor) static void sub_72580(DBloodActor* actor) { - aiChooseDirection(actor, actor->xspr._goalAng); + aiChooseDirection(actor, actor->xspr.goalAng); aiThinkTarget(actor); } @@ -213,7 +213,7 @@ static void sub_725A4(DBloodActor* actor) pDudeExtraE->thinkTime++; else if (pDudeExtraE->thinkTime >= 10 && pDudeExtraE->active) { - actor->xspr._goalAng += 256; + actor->xspr.goalAng += DAngle45; aiSetTarget(actor, actor->basePoint); aiNewState(actor, &tcherno13AA28); return; @@ -264,7 +264,7 @@ static void sub_72850(DBloodActor* actor) auto dvec = actor->xspr.TargetPos.XY() - actor->spr.pos.XY(); int nAngle = getangle(dvec); int nDist = approxDist(dvec); - aiChooseDirection(actor, nAngle); + aiChooseDirection(actor, DAngle::fromBuild(nAngle)); if (nDist < 512 && abs(actor->int_ang() - nAngle) < pDudeInfo->periphery) aiNewState(actor, &tchernobogSearch); aiThinkTarget(actor); @@ -288,7 +288,7 @@ static void sub_72934(DBloodActor* actor) auto dvec = target->spr.pos.XY() - actor->spr.pos.XY(); int nAngle = getangle(dvec); int nDist = approxDist(dvec); - aiChooseDirection(actor, nAngle); + aiChooseDirection(actor, DAngle::fromBuild(nAngle)); if (target->xspr.health == 0) { aiNewState(actor, &tchernobogSearch); diff --git a/source/games/blood/src/aiunicult.cpp b/source/games/blood/src/aiunicult.cpp index f978ceaa2..fcc2543f0 100644 --- a/source/games/blood/src/aiunicult.cpp +++ b/source/games/blood/src/aiunicult.cpp @@ -401,7 +401,7 @@ static void unicultThinkSearch(DBloodActor* actor) { // TO DO: if can't see the target, but in fireDist range - stop moving and look around - aiChooseDirection(actor, actor->xspr._goalAng); + aiChooseDirection(actor, actor->xspr.goalAng); aiLookForTarget(actor); } @@ -423,7 +423,7 @@ static void unicultThinkGoto(DBloodActor* actor) int nAngle = getangle(dvec); int nDist = approxDist(dvec); - aiChooseDirection(actor, nAngle); + aiChooseDirection(actor, DAngle::fromBuild(nAngle)); // if reached target, change to search mode if (nDist < 5120 && abs(actor->int_ang() - nAngle) < getDudeInfo(actor->spr.type)->periphery) @@ -487,13 +487,12 @@ static void unicultThinkChase(DBloodActor* actor) // quick hack to prevent spinning around or changing attacker's sprite angle on high movement speeds // when attacking the target. It happens because vanilla function takes in account x and y velocity, // so i use fake velocity with fixed value and pass it as argument. - int xvelocity = actor->int_vel().X; - int yvelocity = actor->int_vel().Y; + auto velocity = actor->vel; if (inAttack(actor->xspr.aiState)) - xvelocity = yvelocity = ClipLow(actor->spr.clipdist >> 1, 1); + velocity.X = velocity.Y = FixedToFloat(ClipLow(actor->spr.clipdist >> 1, 1)); //aiChooseDirection(actor,getangle(dx, dy)); - aiGenDudeChooseDirection(actor, getangle(dx, dy), xvelocity, yvelocity); + aiGenDudeChooseDirection(actor, VecToAngle(dx, dy), velocity); GENDUDEEXTRA* pExtra = &actor->genDudeExtra; if (!pExtra->canAttack) @@ -899,7 +898,7 @@ static void unicultThinkChase(DBloodActor* actor) { if (spriteIsUnderwater(actor)) aiGenDudeNewState(actor, &genDudeChaseW); else aiGenDudeNewState(actor, &genDudeChaseL); - actor->xspr._goalAng = Random(kAng360); + actor->xspr.goalAng = RandomAngle(); //viewSetSystemMessage("WALL OR SPRITE TOUCH"); } @@ -1110,11 +1109,10 @@ void aiGenDudeMoveForward(DBloodActor* actor) { DUDEINFO* pDudeInfo = getDudeInfo(actor->spr.type); GENDUDEEXTRA* pExtra = &actor->genDudeExtra; - int maxTurn = pDudeInfo->angSpeed * 4 >> 4; if (pExtra->canFly) { - auto nAng = deltaangle(actor->spr.angle, DAngle::fromBuild(actor->xspr._goalAng)); + auto nAng = deltaangle(actor->spr.angle, actor->xspr.goalAng); auto nTurnRange = DAngle::fromQ16(pDudeInfo->angSpeed << 3); actor->spr.angle += clamp(nAng, -nTurnRange, nTurnRange); int nAccel = pDudeInfo->frontSpeed << 2; @@ -1136,19 +1134,17 @@ void aiGenDudeMoveForward(DBloodActor* actor) } else { - int dang = ((kAng180 + actor->xspr._goalAng - actor->int_ang()) & 2047) - kAng180; - actor->set_int_ang(((actor->int_ang() + ClipRange(dang, -maxTurn, maxTurn)) & 2047)); + DAngle maxTurn = DAngle::fromBuild(pDudeInfo->angSpeed * 4 >> 4); + + DAngle dang = actor->xspr.goalAng - actor->spr.angle; + actor->spr.angle += clamp(dang, -maxTurn, maxTurn); // don't move forward if trying to turn around - if (abs(dang) > kAng60) + if (abs(dang) > DAngle180 / 3) return; - int sin = Sin(actor->int_ang()); - int cos = Cos(actor->int_ang()); - - int frontSpeed = actor->genDudeExtra.moveSpeed; - actor->add_int_bvel_x(MulScale(cos, frontSpeed, 30)); - actor->add_int_bvel_y(MulScale(sin, frontSpeed, 30)); + double frontSpeed = FixedToFloat(actor->genDudeExtra.moveSpeed); + actor->vel += actor->spr.angle.ToVector() * frontSpeed; } } @@ -1158,7 +1154,7 @@ void aiGenDudeMoveForward(DBloodActor* actor) // //--------------------------------------------------------------------------- -void aiGenDudeChooseDirection(DBloodActor* actor, int a3, int xvel, int yvel) +void aiGenDudeChooseDirection(DBloodActor* actor, DAngle direction, const DVector2& vel) { if (!(actor->spr.type >= kDudeBase && actor->spr.type < kDudeMax)) { @@ -1168,31 +1164,33 @@ void aiGenDudeChooseDirection(DBloodActor* actor, int a3, int xvel, int yvel) // TO-DO: Take in account if sprite is flip-x, so enemy select correct angle - int vc = getincangle(actor->int_ang(), a3); - int t1 = DMulScale(xvel, Cos(actor->int_ang()), yvel, Sin(actor->int_ang()), 30); - int vsi = ((t1 * 15) >> 12) / 2; int v8 = (vc >= 0) ? 341 : -341; + DAngle vc = deltaangle(actor->spr.angle, direction); + double t1 = vel.X * actor->spr.angle.Cos() + vel.Y * actor->spr.angle.Sin(); + int range = FloatToFixed(t1 * (15 / 8192.)); + DAngle v8 = vc > nullAngle ? DAngle180 / 3 : -DAngle180 / 3; - if (CanMove(actor, actor->GetTarget(), actor->int_ang() + vc, vsi)) - actor->xspr._goalAng = actor->int_ang() + vc; - else if (CanMove(actor, actor->GetTarget(), actor->int_ang() + vc / 2, vsi)) - actor->xspr._goalAng = actor->int_ang() + vc / 2; - else if (CanMove(actor, actor->GetTarget(), actor->int_ang() - vc / 2, vsi)) - actor->xspr._goalAng = actor->int_ang() - vc / 2; - else if (CanMove(actor, actor->GetTarget(), actor->int_ang() + v8, vsi)) - actor->xspr._goalAng = actor->int_ang() + v8; - else if (CanMove(actor, actor->GetTarget(), actor->int_ang(), vsi)) - actor->xspr._goalAng = actor->int_ang(); - else if (CanMove(actor, actor->GetTarget(), actor->int_ang() - v8, vsi)) - actor->xspr._goalAng = actor->int_ang() - v8; + if (CanMove(actor, actor->GetTarget(), actor->spr.angle + vc, range)) + actor->xspr.goalAng = actor->spr.angle + vc; + else if (CanMove(actor, actor->GetTarget(), actor->spr.angle + vc / 2, range)) + actor->xspr.goalAng = actor->spr.angle + vc / 2; + else if (CanMove(actor, actor->GetTarget(), actor->spr.angle - vc / 2, range)) + actor->xspr.goalAng = actor->spr.angle - vc / 2; + else if (CanMove(actor, actor->GetTarget(), actor->spr.angle + v8, range)) + actor->xspr.goalAng = actor->spr.angle + v8; + else if (CanMove(actor, actor->GetTarget(), actor->spr.angle, range)) + actor->xspr.goalAng = actor->spr.angle; + else if (CanMove(actor, actor->GetTarget(), actor->spr.angle - v8, range)) + actor->xspr.goalAng = actor->spr.angle - v8; else - actor->xspr._goalAng = actor->int_ang() + 341; + actor->xspr.goalAng = actor->spr.angle + DAngle180 / 3; + actor->xspr.goalAng = actor->xspr.goalAng.Normalized360(); actor->xspr.dodgeDir = (Chance(0x8000)) ? 1 : -1; - if (!CanMove(actor, actor->GetTarget(), actor->int_ang() + actor->xspr.dodgeDir * 512, 512)) + if (!CanMove(actor, actor->GetTarget(), actor->spr.angle + DAngle90 * actor->xspr.dodgeDir, 512)) { actor->xspr.dodgeDir = -actor->xspr.dodgeDir; - if (!CanMove(actor, actor->GetTarget(), actor->int_ang() + actor->xspr.dodgeDir * 512, 512)) + if (!CanMove(actor, actor->GetTarget(), actor->spr.angle + DAngle90 * actor->xspr.dodgeDir, 512)) actor->xspr.dodgeDir = 0; } } diff --git a/source/games/blood/src/aiunicult.h b/source/games/blood/src/aiunicult.h index fa41dd869..f3c2a1118 100644 --- a/source/games/blood/src/aiunicult.h +++ b/source/games/blood/src/aiunicult.h @@ -200,7 +200,7 @@ DBloodActor* leechIsDropped(DBloodActor* pSprite); bool spriteIsUnderwater(DBloodActor* pSprite, bool oldWay = false); bool playGenDudeSound(DBloodActor* actor, int mode); void aiGenDudeMoveForward(DBloodActor* actor); -void aiGenDudeChooseDirection(DBloodActor* actor, int a3, int aXvel = -1, int aYvel = -1); +void aiGenDudeChooseDirection(DBloodActor* actor, DAngle a3, const DVector2& vel); void aiGenDudeNewState(DBloodActor* actor, AISTATE* pAIState); int checkAttackState(DBloodActor* actor); bool doExplosion(DBloodActor* pSprite, int nType); diff --git a/source/games/blood/src/aizomba.cpp b/source/games/blood/src/aizomba.cpp index b9fbd8656..a1bc40783 100644 --- a/source/games/blood/src/aizomba.cpp +++ b/source/games/blood/src/aizomba.cpp @@ -83,7 +83,7 @@ void StandSeqCallback(int, DBloodActor* actor) static void zombaThinkSearch(DBloodActor* actor) { - aiChooseDirection(actor, actor->xspr._goalAng); + aiChooseDirection(actor, actor->xspr.goalAng); aiLookForTarget(actor); } @@ -94,7 +94,7 @@ static void zombaThinkGoto(DBloodActor* actor) auto dvec = actor->xspr.TargetPos.XY() - actor->spr.pos.XY(); int nAngle = getangle(dvec); int nDist = approxDist(dvec); - aiChooseDirection(actor, nAngle); + aiChooseDirection(actor, DAngle::fromBuild(nAngle)); if (nDist < 921 && abs(actor->int_ang() - nAngle) < pDudeInfo->periphery) aiNewState(actor, &zombieASearch); aiThinkTarget(actor); @@ -115,7 +115,7 @@ static void zombaThinkChase(DBloodActor* actor) auto dvec = target->spr.pos.XY() - actor->spr.pos.XY(); int nAngle = getangle(dvec); int nDist = approxDist(dvec); - aiChooseDirection(actor, nAngle); + aiChooseDirection(actor, DAngle::fromBuild(nAngle)); if (target->xspr.health == 0) { @@ -167,7 +167,7 @@ static void zombaThinkPonder(DBloodActor* actor) auto dvec = target->spr.pos.XY() - actor->spr.pos.XY(); int nAngle = getangle(dvec); int nDist = approxDist(dvec); - aiChooseDirection(actor, nAngle); + aiChooseDirection(actor, DAngle::fromBuild(nAngle)); if (target->xspr.health == 0) { aiNewState(actor, &zombieASearch); @@ -248,7 +248,7 @@ static void myThinkTarget(DBloodActor* actor) static void myThinkSearch(DBloodActor* actor) { - aiChooseDirection(actor, actor->xspr._goalAng); + aiChooseDirection(actor, actor->xspr.goalAng); myThinkTarget(actor); } diff --git a/source/games/blood/src/aizombf.cpp b/source/games/blood/src/aizombf.cpp index de83430ba..fb7d1477f 100644 --- a/source/games/blood/src/aizombf.cpp +++ b/source/games/blood/src/aizombf.cpp @@ -82,7 +82,7 @@ void ThrowSeqCallback(int, DBloodActor* actor) static void zombfThinkSearch(DBloodActor* actor) { - aiChooseDirection(actor, actor->xspr._goalAng); + aiChooseDirection(actor, actor->xspr.goalAng); aiThinkTarget(actor); } @@ -93,7 +93,7 @@ static void zombfThinkGoto(DBloodActor* actor) auto dvec = actor->xspr.TargetPos.XY() - actor->spr.pos.XY(); int nAngle = getangle(dvec); int nDist = approxDist(dvec); - aiChooseDirection(actor, nAngle); + aiChooseDirection(actor, DAngle::fromBuild(nAngle)); if (nDist < 512 && abs(actor->int_ang() - nAngle) < pDudeInfo->periphery) aiNewState(actor, &zombieFSearch); aiThinkTarget(actor); @@ -113,7 +113,7 @@ static void zombfThinkChase(DBloodActor* actor) int dx = target->int_pos().X - actor->int_pos().X; int dy = target->int_pos().Y - actor->int_pos().Y; - aiChooseDirection(actor, getangle(dx, dy)); + aiChooseDirection(actor, VecToAngle(dx, dy)); if (target->xspr.health == 0) { aiNewState(actor, &zombieFSearch); diff --git a/source/games/blood/src/db.cpp b/source/games/blood/src/db.cpp index 0556e5b9b..278da4c60 100644 --- a/source/games/blood/src/db.cpp +++ b/source/games/blood/src/db.cpp @@ -549,7 +549,7 @@ void dbLoadMap(const char* pPath, DVector3& pos, short* pAngle, int* cursectnum, pXSprite->data1 = bitReader.readSigned(16); pXSprite->data2 = bitReader.readSigned(16); pXSprite->data3 = bitReader.readSigned(16); - pXSprite->_goalAng = bitReader.readUnsigned(11); + pXSprite->goalAng = DAngle::fromBuild(bitReader.readUnsigned(11)); pXSprite->dodgeDir = bitReader.readSigned(2); pXSprite->locked = bitReader.readUnsigned(1); pXSprite->medium = bitReader.readUnsigned(2); diff --git a/source/games/blood/src/loadsave.cpp b/source/games/blood/src/loadsave.cpp index 99021ee8a..29dc5367e 100644 --- a/source/games/blood/src/loadsave.cpp +++ b/source/games/blood/src/loadsave.cpp @@ -634,7 +634,7 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, XSPRITE& w, XSPRIT ("burnsource", w.burnSource, def->burnSource) ("busytime", w.busyTime, def->busyTime) ("waittime", w.waitTime, def->waitTime) - ("goalang", w._goalAng, def->_goalAng) + ("goalang", w.goalAng, def->goalAng) ("burntime", w.burnTime, def->burnTime) ("height", w.height, def->height) ("statetimer", w.stateTimer, def->stateTimer) diff --git a/source/games/blood/src/mapstructs.h b/source/games/blood/src/mapstructs.h index 1cc7e657b..423bc091c 100644 --- a/source/games/blood/src/mapstructs.h +++ b/source/games/blood/src/mapstructs.h @@ -104,7 +104,7 @@ struct XSPRITE { const vec3_t int_TargetPos() const { return { int(TargetPos.X * worldtoint), int(TargetPos.Y * worldtoint), int(TargetPos.Z * worldtoint)}; } DVector3 TargetPos; - uint16_t _goalAng; // Dude goal ang + DAngle goalAng; // Dude goal ang int32_t sysData1; // used to keep here various system data, so user can't change it in map editor int32_t sysData2; // diff --git a/source/games/blood/src/nnexts.cpp b/source/games/blood/src/nnexts.cpp index 017137dff..b1967c08b 100644 --- a/source/games/blood/src/nnexts.cpp +++ b/source/games/blood/src/nnexts.cpp @@ -1295,13 +1295,13 @@ void nnExtProcessSuperSprites() int mass = debrisactor->spriteMass.mass; int airVel = debrisactor->spriteMass.airVel; - int top, bottom; + double top, bottom; GetActorExtents(debrisactor, &top, &bottom); if (pXSector != nullptr) { if ((uwater = pXSector->Underwater) != 0) airVel <<= 6; - if (pXSector->panVel != 0 && getflorzofslopeptr(debrisactor->sector(), debrisactor->int_pos().X, debrisactor->int_pos().Y) <= bottom) + if (pXSector->panVel != 0 && getflorzofslopeptrf(debrisactor->sector(), debrisactor->spr.pos) <= bottom) { int angle = pXSector->panAngle; int speed = 0; if (pXSector->panAlways || pXSector->state || pXSector->busy) @@ -1347,31 +1347,35 @@ void nnExtProcessSuperSprites() debrisMove(i); if (debrisactor->vel.X != 0 || debrisactor->int_vel().Y) - debrisactor->xspr._goalAng = getangle(debrisactor->vel) & 2047; + debrisactor->xspr.goalAng = VecToAngle(debrisactor->vel); - int ang = debrisactor->int_ang() & 2047; + debrisactor->norm_ang(); + DAngle ang = debrisactor->spr.angle; if ((uwater = spriteIsUnderwater(debrisactor)) == false) evKillActor(debrisactor, kCallbackEnemeyBubble); else if (Chance(0x1000 - mass)) { if (debrisactor->vel.Z > 0x100) debrisBubble(debrisactor); - if (ang == debrisactor->xspr._goalAng) + if (absangle(ang, debrisactor->xspr.goalAng) < minAngle) // need to be very careful with comparing angles for equality! { - debrisactor->xspr._goalAng = (debrisactor->int_ang() + Random3(kAng60)) & 2047; + debrisactor->xspr.goalAng += RandomAngle(kAng60); + debrisactor->norm_ang(); debrisBubble(debrisactor); } } - int angStep = ClipLow(mulscale8(1, ((abs(debrisactor->int_vel().X) + abs(debrisactor->int_vel().Y)) >> 5)), (uwater) ? 1 : 0); - if (ang < debrisactor->xspr._goalAng) debrisactor->set_int_ang(ClipHigh(ang + angStep, debrisactor->xspr._goalAng)); - else if (ang > debrisactor->xspr._goalAng) debrisactor->set_int_ang(ClipLow(ang - angStep, debrisactor->xspr._goalAng)); + int vdist = max((int)(abs(debrisactor->vel.X) + abs(debrisactor->vel.Y) * 2048.), (uwater) ? 1 : 0); + auto angStep = DAngle::fromBuild(vdist); + + if (ang < debrisactor->xspr.goalAng) debrisactor->spr.angle = min(ang + angStep, debrisactor->xspr.goalAng); + else if (ang > debrisactor->xspr.goalAng) debrisactor->spr.angle = max(ang - angStep, debrisactor->xspr.goalAng); auto pSector = debrisactor->sector(); - int cz = getceilzofslopeptr(pSector, debrisactor->int_pos().X, debrisactor->int_pos().Y); - int fz = getflorzofslopeptr(pSector, debrisactor->int_pos().X, debrisactor->int_pos().Y); - + double fz, cz; + getzsofslopeptr(pSector, debrisactor->spr.pos, &cz, &fz); GetActorExtents(debrisactor, &top, &bottom); - if (fz >= bottom && pSector->lowerLink == nullptr && !(pSector->ceilingstat & CSTAT_SECTOR_SKY)) debrisactor->add_int_z(ClipLow(cz - top, 0)); - if (cz <= top && pSector->upperLink == nullptr && !(pSector->floorstat & CSTAT_SECTOR_SKY)) debrisactor->add_int_z(ClipHigh(fz - bottom, 0)); + + if (fz >= bottom && pSector->lowerLink == nullptr && !(pSector->ceilingstat & CSTAT_SECTOR_SKY)) debrisactor->spr.pos.Z += max(cz - top, 0.); + if (cz <= top && pSector->upperLink == nullptr && !(pSector->floorstat & CSTAT_SECTOR_SKY)) debrisactor->spr.pos.Z += min(fz - bottom, 0.); } } } @@ -2783,8 +2787,8 @@ void usePropertiesChanger(DBloodActor* sourceactor, int objType, sectortype* pSe if (targetactor->spr.statnum == kStatThing) ChangeActorStat(targetactor, 0); // set random goal ang for swimming so they start turning - if ((flags & kPhysDebrisSwim) && targetactor->int_vel().X ==0 && targetactor->vel.Y == 0 && targetactor->vel.Z == 0) - targetactor->xspr._goalAng = (targetactor->int_ang() + Random3(kAng45)) & 2047; + if ((flags & kPhysDebrisSwim) && targetactor->vel.isZero()) + targetactor->xspr.goalAng = (targetactor->spr.angle + DAngle::fromBuild(Random3(kAng45))).Normalized360(); if (targetactor->xspr.physAttr & kPhysDebrisVector) targetactor->spr.cstat |= CSTAT_SPRITE_BLOCK_HITSCAN; @@ -7694,8 +7698,9 @@ bool setDataValueOfObject(int objType, sectortype* sect, walltype* wal, DBloodAc // //--------------------------------------------------------------------------- -bool nnExtCanMove(DBloodActor* actor, DBloodActor* target, int nAngle, int nRange) +bool nnExtCanMove(DBloodActor* actor, DBloodActor* target, DAngle nAngle_, int nRange) { + int nAngle = nAngle_.Buildang(); int x = actor->int_pos().X, y = actor->int_pos().Y, z = actor->int_pos().Z; auto pSector = actor->sector(); HitScan(actor, z, Cos(nAngle) >> 16, Sin(nAngle) >> 16, 0, CLIPMASK0, nRange); @@ -7725,39 +7730,38 @@ bool nnExtCanMove(DBloodActor* actor, DBloodActor* target, int nAngle, int nRang // //--------------------------------------------------------------------------- -void nnExtAiSetDirection(DBloodActor* actor, int a3) +void nnExtAiSetDirection(DBloodActor* actor, DAngle direction) { assert(actor->spr.type >= kDudeBase && actor->spr.type < kDudeMax); - int vc = getincangle(actor->int_ang(), a3); - int t1 = DMulScale(actor->int_vel().X, Cos(actor->int_ang()), actor->int_vel().Y, Sin(actor->int_ang()), 30); - int vsi = ((t1 * 15) >> 12) / 2; - int v8 = 341; + DAngle vc = deltaangle(actor->spr.angle, direction); + double nCos = actor->spr.angle.Cos(); + double nSin = actor->spr.angle.Sin(); + double t1 = actor->vel.X * nCos + actor->vel.Y * nSin; + int range = FloatToFixed(t1 * (15 / 8192.)); + DAngle v8 = vc > nullAngle ? DAngle180 / 3 : -DAngle180 / 3; - if (vc < 0) - v8 = -341; - - if (nnExtCanMove(actor, actor->GetTarget(), actor->int_ang() + vc, vsi)) - actor->xspr._goalAng = actor->int_ang() + vc; - else if (nnExtCanMove(actor, actor->GetTarget(), actor->int_ang() + vc / 2, vsi)) - actor->xspr._goalAng = actor->int_ang() + vc / 2; - else if (nnExtCanMove(actor, actor->GetTarget(), actor->int_ang() - vc / 2, vsi)) - actor->xspr._goalAng = actor->int_ang() - vc / 2; - else if (nnExtCanMove(actor, actor->GetTarget(), actor->int_ang() + v8, vsi)) - actor->xspr._goalAng = actor->int_ang() + v8; - else if (nnExtCanMove(actor, actor->GetTarget(), actor->int_ang(), vsi)) - actor->xspr._goalAng = actor->int_ang(); - else if (nnExtCanMove(actor, actor->GetTarget(), actor->int_ang() - v8, vsi)) - actor->xspr._goalAng = actor->int_ang() - v8; + if (nnExtCanMove(actor, actor->GetTarget(), actor->spr.angle + vc, range)) + actor->xspr.goalAng = actor->spr.angle + vc; + else if (nnExtCanMove(actor, actor->GetTarget(), actor->spr.angle + vc / 2, range)) + actor->xspr.goalAng = actor->spr.angle + vc / 2; + else if (nnExtCanMove(actor, actor->GetTarget(), actor->spr.angle - vc / 2, range)) + actor->xspr.goalAng = actor->spr.angle - vc / 2; + else if (nnExtCanMove(actor, actor->GetTarget(), actor->spr.angle + v8, range)) + actor->xspr.goalAng = actor->spr.angle + v8; + else if (nnExtCanMove(actor, actor->GetTarget(), actor->spr.angle, range)) + actor->xspr.goalAng = actor->spr.angle; + else if (nnExtCanMove(actor, actor->GetTarget(), actor->spr.angle - v8, range)) + actor->xspr.goalAng = actor->spr.angle - v8; else - actor->xspr._goalAng = actor->int_ang() + 341; + actor->xspr.goalAng = actor->spr.angle + DAngle180 / 3; if (actor->xspr.dodgeDir) { - if (!nnExtCanMove(actor, actor->GetTarget(), actor->int_ang() + actor->xspr.dodgeDir * 512, 512)) + if (!nnExtCanMove(actor, actor->GetTarget(), actor->spr.angle + DAngle90 * actor->xspr.dodgeDir, 512)) { actor->xspr.dodgeDir = -actor->xspr.dodgeDir; - if (!nnExtCanMove(actor, actor->GetTarget(), actor->int_ang() + actor->xspr.dodgeDir * 512, 512)) + if (!nnExtCanMove(actor, actor->GetTarget(), actor->spr.angle + DAngle90 * actor->xspr.dodgeDir, 512)) actor->xspr.dodgeDir = 0; } } @@ -8122,17 +8126,17 @@ void aiPatrolStop(DBloodActor* actor, DBloodActor* targetactor, bool alarm) void aiPatrolRandGoalAng(DBloodActor* actor) { - int goal = kAng90; + DAngle goal = DAngle90; if (Chance(0x4000)) - goal = kAng120; + goal = DAngle360 / 3; if (Chance(0x4000)) - goal = kAng180; + goal = DAngle180; if (Chance(0x8000)) goal = -goal; - actor->xspr._goalAng = (actor->int_ang() + goal) & 2047; + actor->xspr.goalAng = (actor->spr.angle + goal).Normalized360(); } //--------------------------------------------------------------------------- @@ -8143,9 +8147,9 @@ void aiPatrolRandGoalAng(DBloodActor* actor) void aiPatrolTurn(DBloodActor* actor) { - int nTurnRange = (getDudeInfo(actor->spr.type)->angSpeed << 1) >> 4; - int nAng = getincangle(actor->int_ang(), actor->xspr._goalAng); - actor->set_int_ang((actor->int_ang() + ClipRange(nAng, -nTurnRange, nTurnRange)) & 2047); + DAngle nTurnRange = DAngle::fromBuild((getDudeInfo(actor->spr.type)->angSpeed << 1) >> 4); + DAngle nAng = deltaangle(actor->spr.angle, actor->xspr.goalAng); + actor->spr.angle += clamp(nAng, -nTurnRange, nTurnRange); } @@ -8177,11 +8181,11 @@ void aiPatrolMove(DBloodActor* actor) int dy = (targetactor->int_pos().Y - actor->int_pos().Y); int dz = (targetactor->int_pos().Z - (actor->int_pos().Z - pDudeInfo->eyeHeight)) * 6; int vel = (actor->xspr.unused1 & kDudeFlagCrouch) ? kMaxPatrolCrouchVelocity : kMaxPatrolVelocity; - int goalAng = 341; + DAngle goalAng = DAngle180 / 3; if (pExtra->flying || spriteIsUnderwater(actor)) { - goalAng >>= 1; + goalAng *= 0.5; actor->set_int_bvel_z(dz); if (actor->spr.flags & kPhysGravity) actor->spr.flags &= ~kPhysGravity; @@ -8191,9 +8195,10 @@ void aiPatrolMove(DBloodActor* actor) actor->spr.flags |= kPhysGravity | kPhysFalling; } - int nTurnRange = (pDudeInfo->angSpeed << 2) >> 4; - int nAng = getincangle(actor->int_ang(), actor->xspr._goalAng); - actor->set_int_ang((actor->int_ang() + ClipRange(nAng, -nTurnRange, nTurnRange)) & 2047); + DAngle nTurnRange = DAngle::fromBuild((pDudeInfo->angSpeed << 2) >> 4); + DAngle nAng = deltaangle(actor->spr.angle, actor->xspr.goalAng); + actor->spr.angle += clamp(nAng, -nTurnRange, nTurnRange); + if (abs(nAng) > goalAng || ((targetactor->xspr.waitTime > 0 || targetactor->xspr.data1 == targetactor->xspr.data2) && aiPatrolMarkerReached(actor))) { @@ -8873,7 +8878,7 @@ void aiPatrolThink(DBloodActor* actor) else if (aiPatrolTurning(actor->xspr.aiState)) { //viewSetSystemMessage("TURN"); - if ((int)actor->int_ang() == (int)actor->xspr._goalAng) + if (absangle(actor->spr.angle, actor->xspr.goalAng) < minAngle) { // save imer for waiting stateTimer = actor->xspr.stateTimer; @@ -8904,8 +8909,8 @@ void aiPatrolThink(DBloodActor* actor) // take marker's angle if (!(markeractor->spr.flags & kModernTypeFlag4)) { - actor->xspr._goalAng = ((!(markeractor->spr.flags & kModernTypeFlag8) && actor->xspr.unused2) ? markeractor->int_ang() + kAng180 : markeractor->int_ang()) & 2047; - if ((int)actor->int_ang() != (int)actor->xspr._goalAng) // let the enemy play move animation while turning + actor->xspr.goalAng = ((!(markeractor->spr.flags & kModernTypeFlag8) && actor->xspr.unused2) ? markeractor->spr.angle+ DAngle180 : markeractor->spr.angle).Normalized360(); + if (absangle(actor->spr.angle, actor->xspr.goalAng) > minAngle) // let the enemy play move animation while turning return; } @@ -8980,7 +8985,7 @@ void aiPatrolThink(DBloodActor* actor) } } - nnExtAiSetDirection(actor, getangle(markeractor->int_pos().X - actor->int_pos().X, markeractor->int_pos().Y - actor->int_pos().Y)); + nnExtAiSetDirection(actor, VecToAngle(markeractor->spr.pos - actor->spr.pos)); if (aiPatrolMoving(actor->xspr.aiState) && !reached) return; else if (uwater) aiPatrolState(actor, kAiStatePatrolMoveW); @@ -9331,7 +9336,7 @@ void changeSpriteAngle(DBloodActor* pSpr, int nAng) { pSpr->set_int_ang(nAng); if (pSpr->hasX()) - pSpr->xspr._goalAng = pSpr->int_ang(); + pSpr->xspr.goalAng = pSpr->spr.angle; } } }