- aiPatrolSearchTargets

This commit is contained in:
Christoph Oelckers 2021-09-04 10:44:08 +02:00
parent c2ff8b0941
commit bf424b6439

View file

@ -8215,9 +8215,11 @@ bool readyForCrit(DBloodActor* hunter, DBloodActor* victim)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
int aiPatrolSearchTargets(spritetype* pSprite, XSPRITE* pXSprite) { DBloodActor* aiPatrolSearchTargets(DBloodActor* actor)
{
spritetype* pSprite = &actor->s();
XSPRITE* pXSprite = &actor->x();
auto actor = &bloodActors[pSprite->index];
enum { kMaxPatrolFoundSounds = 256 }; // should be the maximum amount of sound channels the engine can play at the same time. enum { kMaxPatrolFoundSounds = 256 }; // should be the maximum amount of sound channels the engine can play at the same time.
PATROL_FOUND_SOUNDS patrolBonkles[kMaxPatrolFoundSounds]; PATROL_FOUND_SOUNDS patrolBonkles[kMaxPatrolFoundSounds];
@ -8230,22 +8232,25 @@ int aiPatrolSearchTargets(spritetype* pSprite, XSPRITE* pXSprite) {
patrolBonkles[i].max = ClipLow((gGameOptions.nDifficulty + 1) >> 1, 1); patrolBonkles[i].max = ClipLow((gGameOptions.nDifficulty + 1) >> 1, 1);
} }
int i, j, f, mod, x, y, z, dx, dy, nDist, eyeAboveZ, target = -1, sndCnt = 0, seeDist, hearDist, feelDist, seeChance, hearChance; int i, j, f, mod, x, y, z, dx, dy, nDist, eyeAboveZ, sndCnt = 0, seeDist, hearDist, feelDist, seeChance, hearChance;
bool stealth = (pXSprite->unused1 & kDudeFlagStealth); bool blind = (pXSprite->dudeGuard); bool deaf = (pXSprite->dudeDeaf); bool stealth = (pXSprite->unused1 & kDudeFlagStealth);
bool blind = (pXSprite->dudeGuard);
bool deaf = (pXSprite->dudeDeaf);
DBloodActor* newtarget = nullptr;
// search for player targets // search for player targets
for (i = connecthead; i != -1; i = connectpoint2[i]) { for (i = connecthead; i != -1; i = connectpoint2[i])
{
pPlayer = &gPlayer[i]; pPlayer = &gPlayer[i];
spritetype* pSpr = pPlayer->pSprite; if (!pPlayer->actor()->hasX()) continue;
if (!xsprIsFine(pSpr))
continue;
XSPRITE* pXSpr = &xsprite[pSpr->extra]; spritetype* pSpr = pPlayer->pSprite;
XSPRITE* pXSpr = &pPlayer->actor()->x();
if (pXSpr->health <= 0) if (pXSpr->health <= 0)
continue; continue;
target = -1; seeChance = hearChance = 0x0000; newtarget = nullptr;
seeChance = hearChance = 0x0000;
x = pSpr->x, y = pSpr->y, z = pSpr->z, dx = x - pSprite->x, dy = y - pSprite->y; nDist = approxDist(dx, dy); x = pSpr->x, y = pSpr->y, z = pSpr->z, dx = x - pSprite->x, dy = y - pSprite->y; nDist = approxDist(dx, dy);
seeDist = (stealth) ? pDudeInfo->seeDist / 3 : pDudeInfo->seeDist >> 1; seeDist = (stealth) ? pDudeInfo->seeDist / 3 : pDudeInfo->seeDist >> 1;
hearDist = pDudeInfo->hearDist; feelDist = hearDist >> 1; hearDist = pDudeInfo->hearDist; feelDist = hearDist >> 1;
@ -8256,7 +8261,7 @@ int aiPatrolSearchTargets(spritetype* pSprite, XSPRITE* pXSprite) {
if (nDist <= seeDist) if (nDist <= seeDist)
{ {
eyeAboveZ = (pDudeInfo->eyeHeight * pSprite->yrepeat) << 2; eyeAboveZ = (pDudeInfo->eyeHeight * pSprite->yrepeat) << 2;
if (nDist < seeDist >> 3) GetSpriteExtents(pSpr, &z, &j); //use ztop of the target sprite if (nDist < seeDist >> 3) GetActorExtents(pPlayer->actor(), &z, &j); //use ztop of the target sprite
if (!cansee(x, y, z, pSpr->sectnum, pSprite->x, pSprite->y, pSprite->z - eyeAboveZ, pSprite->sectnum)) if (!cansee(x, y, z, pSpr->sectnum, pSprite->x, pSprite->y, pSprite->z - eyeAboveZ, pSprite->sectnum))
continue; continue;
} }
@ -8266,9 +8271,9 @@ int aiPatrolSearchTargets(spritetype* pSprite, XSPRITE* pXSprite) {
bool invisible = (powerupCheck(pPlayer, kPwUpShadowCloak) > 0); bool invisible = (powerupCheck(pPlayer, kPwUpShadowCloak) > 0);
if (spritesTouching(actor, pPlayer->actor()) || spritesTouching(pPlayer->actor(), actor)) if (spritesTouching(actor, pPlayer->actor()) || spritesTouching(pPlayer->actor(), actor))
{ {
DPrintf(DMSG_SPAMMY, "Patrol dude #%d spot the Player #%d via touch.", pSprite->index, pPlayer->nPlayer + 1); DPrintf(DMSG_SPAMMY, "Patrol dude #%d spot the Player #%d via touch.", actor->GetIndex(), pPlayer->nPlayer + 1);
if (invisible) pPlayer->pwUpTime[kPwUpShadowCloak] = 0; if (invisible) pPlayer->pwUpTime[kPwUpShadowCloak] = 0;
target = pSpr->index; newtarget = pPlayer->actor();
break; break;
} }
@ -8322,7 +8327,7 @@ int aiPatrolSearchTargets(spritetype* pSprite, XSPRITE* pXSprite) {
BloodSectIterator it(searchsect); BloodSectIterator it(searchsect);
while (auto act = it.Next()) while (auto act = it.Next())
{ {
if (act->GetOwner() == &bloodActors[pSpr->index]) if (act->GetOwner() == pPlayer->actor())
{ {
found = true; found = true;
break; break;
@ -8338,12 +8343,11 @@ int aiPatrolSearchTargets(spritetype* pSprite, XSPRITE* pXSprite) {
if (invisible && hearChance >= kMaxPatrolSpotValue >> 2) if (invisible && hearChance >= kMaxPatrolSpotValue >> 2)
{ {
target = pSpr->index; newtarget = pPlayer->actor();
pPlayer->pwUpTime[kPwUpShadowCloak] = 0; pPlayer->pwUpTime[kPwUpShadowCloak] = 0;
invisible = false; invisible = false;
break; break;
} }
} }
if (!invisible && (!deaf || !blind)) if (!invisible && (!deaf || !blind))
@ -8377,17 +8381,18 @@ int aiPatrolSearchTargets(spritetype* pSprite, XSPRITE* pXSprite) {
} }
break; break;
} }
} }
bool itCanHear = false; bool itCanSee = false; bool itCanHear = false; bool itCanSee = false;
feelDist = ClipLow(feelDist, 0); seeDist = ClipLow(seeDist, 0); feelDist = ClipLow(feelDist, 0);
seeDist = ClipLow(seeDist, 0);
if (hearDist) if (hearDist)
{ {
auto act = pPlayer->actor();
itCanHear = (!deaf && (nDist < hearDist || hearChance > 0)); itCanHear = (!deaf && (nDist < hearDist || hearChance > 0));
if (itCanHear && nDist < feelDist && (xvel[pSpr->index] || yvel[pSpr->index] || zvel[pSpr->index])) if (itCanHear && nDist < feelDist && (act->xvel() || act->yvel() || act->zvel()))
hearChance += ClipLow(mulscale8(1, ClipLow(((feelDist - nDist) + (abs(xvel[pSpr->index]) + abs(yvel[pSpr->index]) + abs(zvel[pSpr->index]))) >> 6, 0)), 0); hearChance += ClipLow(mulscale8(1, ClipLow(((feelDist - nDist) + (abs(act->xvel()) + abs(act->yvel()) + abs(act->zvel()))) >> 6, 0)), 0);
} }
if (seeDist) if (seeDist)
@ -8416,12 +8421,13 @@ int aiPatrolSearchTargets(spritetype* pSprite, XSPRITE* pXSprite) {
if (stealth) if (stealth)
{ {
// search in stealth regions to modify spot chances // search in stealth regions to modify spot chances
for (j = headspritestat[kStatModernStealthRegion]; j != -1; j = nextspritestat[j]) { BloodStatIterator it(kStatModernStealthRegion);
while (auto iactor = it.Next())
spritetype* pSteal = &sprite[j]; {
if (!xspriRangeIsFine(pSteal->extra)) if (!iactor->hasX())
continue; continue;
spritetype* pSteal = &iactor->s();
XSPRITE* pXSteal = &xsprite[pSteal->extra]; XSPRITE* pXSteal = &xsprite[pSteal->extra];
if (pXSteal->locked) // ignore locked regions if (pXSteal->locked) // ignore locked regions
continue; continue;
@ -8485,7 +8491,7 @@ int aiPatrolSearchTargets(spritetype* pSprite, XSPRITE* pXSprite) {
// trigger this region if target gonna be spot // trigger this region if target gonna be spot
if (pXSteal->txID && pXSprite->data3 + hearChance + seeChance >= kMaxPatrolSpotValue) if (pXSteal->txID && pXSprite->data3 + hearChance + seeChance >= kMaxPatrolSpotValue)
trTriggerSprite(pSteal->index, pXSteal, kCmdToggle); trTriggerSprite(iactor, kCmdToggle);
// continue search another stealth regions to affect chances // continue search another stealth regions to affect chances
} }
@ -8493,11 +8499,11 @@ int aiPatrolSearchTargets(spritetype* pSprite, XSPRITE* pXSprite) {
if (itCanHear && hearChance > 0) if (itCanHear && hearChance > 0)
{ {
DPrintf(DMSG_SPAMMY, "Patrol dude #%d hearing the Player #%d.", pSprite->index, pPlayer->nPlayer + 1); DPrintf(DMSG_SPAMMY, "Patrol dude #%d hearing the Player #%d.", actor->GetIndex(), pPlayer->nPlayer + 1);
pXSprite->data3 = ClipRange(pXSprite->data3 + hearChance, -kMaxPatrolSpotValue, kMaxPatrolSpotValue); pXSprite->data3 = ClipRange(pXSprite->data3 + hearChance, -kMaxPatrolSpotValue, kMaxPatrolSpotValue);
if (!stealth) if (!stealth)
{ {
target = pSpr->index; newtarget = pPlayer->actor();
break; break;
} }
} }
@ -8509,7 +8515,7 @@ int aiPatrolSearchTargets(spritetype* pSprite, XSPRITE* pXSprite) {
pXSprite->data3 = ClipRange(pXSprite->data3 + seeChance, -kMaxPatrolSpotValue, kMaxPatrolSpotValue); pXSprite->data3 = ClipRange(pXSprite->data3 + seeChance, -kMaxPatrolSpotValue, kMaxPatrolSpotValue);
if (!stealth) if (!stealth)
{ {
target = pSpr->index; newtarget = pPlayer->actor();
break; break;
} }
} }
@ -8519,7 +8525,7 @@ int aiPatrolSearchTargets(spritetype* pSprite, XSPRITE* pXSprite) {
if ((pXSprite->data3 = ClipRange(pXSprite->data3, 0, kMaxPatrolSpotValue)) == kMaxPatrolSpotValue) if ((pXSprite->data3 = ClipRange(pXSprite->data3, 0, kMaxPatrolSpotValue)) == kMaxPatrolSpotValue)
{ {
target = pSpr->index; newtarget = pPlayer->actor();
break; break;
} }
@ -8528,9 +8534,9 @@ int aiPatrolSearchTargets(spritetype* pSprite, XSPRITE* pXSprite) {
} }
if (target >= 0) return target; if (newtarget) return newtarget;
pXSprite->data3 -= ClipLow(((kPercFull * pXSprite->data3) / kMaxPatrolSpotValue) >> 2, 3); pXSprite->data3 -= ClipLow(((kPercFull * pXSprite->data3) / kMaxPatrolSpotValue) >> 2, 3);
return -1; return nullptr;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -8599,9 +8605,11 @@ void aiPatrolThink(DBloodActor* actor) {
assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
int nTarget, stateTimer, nMarker = pXSprite->target_i; DBloodActor* targetactor;
if ((nTarget = aiPatrolSearchTargets(pSprite, pXSprite)) != -1) { int stateTimer, nMarker = pXSprite->target_i;
aiPatrolStop(actor, &bloodActors[nTarget], pXSprite->dudeAmbush); if ((targetactor = aiPatrolSearchTargets(actor)) != nullptr)
{
aiPatrolStop(actor, targetactor, pXSprite->dudeAmbush);
return; return;
} }