- reformatting commit.

# Conflicts:
#	source/games/blood/src/ai.cpp
This commit is contained in:
Christoph Oelckers 2021-09-20 20:42:23 +02:00
parent 062b3dbf76
commit 9de6c7df46
2 changed files with 146 additions and 68 deletions

View file

@ -1273,7 +1273,8 @@ void RecoilDude(DBloodActor* actor)
#ifdef NOONE_EXTENSIONS
case kDudeModernCustom:
{
GENDUDEEXTRA* pExtra = &actor->genDudeExtra(); int rChance = getRecoilChance(pSprite);
GENDUDEEXTRA* pExtra = &actor->genDudeExtra();
int rChance = getRecoilChance(pSprite);
if (pExtra->canElectrocute && pDudeExtra->teslaHit && !spriteIsUnderwater(pSprite, false))
{

View file

@ -453,7 +453,8 @@ static void unicultThinkGoto(DBloodActor* actor)
aiChooseDirection(actor,nAngle);
// if reached target, change to search mode
if (approxDist(dx, dy) < 5120 && abs(pSprite->ang - nAngle) < getDudeInfo(pSprite->type)->periphery) {
if (approxDist(dx, dy) < 5120 && abs(pSprite->ang - nAngle) < getDudeInfo(pSprite->type)->periphery)
{
if (spriteIsUnderwater(pSprite, false)) aiGenDudeNewState(pSprite, &genDudeSearchW);
else aiGenDudeNewState(pSprite, &genDudeSearchL);
}
@ -496,7 +497,8 @@ static void unicultThinkChase(DBloodActor* actor)
if (pXTarget->health <= 0) // target is dead
{
PLAYER* pPlayer = NULL;
if ((!IsPlayerSprite(pTarget)) || ((pPlayer = getPlayerById(pTarget->type)) != NULL && pPlayer->fraggerId == pSprite->index)) {
if ((!IsPlayerSprite(pTarget)) || ((pPlayer = getPlayerById(pTarget->type)) != NULL && pPlayer->fraggerId == pSprite->index))
{
playGenDudeSound(pSprite, kGenDudeSndTargetDead);
if (spriteIsUnderwater(pSprite, false)) aiGenDudeNewState(pSprite, &genDudeSearchShortW);
else aiGenDudeNewState(pSprite, &genDudeSearchShortL);
@ -528,9 +530,12 @@ static void unicultThinkChase(DBloodActor* actor)
if (spriteIsUnderwater(pSprite, false)) aiGenDudeNewState(pSprite, &genDudeGotoW);
else aiGenDudeNewState(pSprite, &genDudeGotoL);
return;
} else if (IsPlayerSprite(pTarget)) {
}
else if (IsPlayerSprite(pTarget))
{
PLAYER* pPlayer = &gPlayer[pTarget->type - kDudePlayer1];
if (powerupCheck(pPlayer, kPwUpShadowCloak) > 0) {
if (powerupCheck(pPlayer, kPwUpShadowCloak) > 0)
{
if (spriteIsUnderwater(pSprite, false)) aiGenDudeNewState(pSprite, &genDudeSearchShortW);
else aiGenDudeNewState(pSprite, &genDudeSearchShortL);
actor->SetTarget(nullptr);
@ -543,8 +548,8 @@ static void unicultThinkChase(DBloodActor* actor)
int eyeAboveZ = (pDudeInfo->eyeHeight * pSprite->yrepeat) << 2;
if (dist > pDudeInfo->seeDist || !cansee(pTarget->x, pTarget->y, pTarget->z, pTarget->sectnum,
pSprite->x, pSprite->y, pSprite->z - eyeAboveZ, pSprite->sectnum)) {
pSprite->x, pSprite->y, pSprite->z - eyeAboveZ, pSprite->sectnum))
{
if (spriteIsUnderwater(pSprite, false)) aiGenDudeNewState(pSprite, &genDudeSearchW);
else aiGenDudeNewState(pSprite, &genDudeSearchL);
actor->SetTarget(nullptr);
@ -573,7 +578,9 @@ static void unicultThinkChase(DBloodActor* actor)
else aiGenDudeNewState(pSprite, &genDudeChaseL);
return;
} else if (dist < 12264 && dist > 7680 && !spriteIsUnderwater(pSprite, false) && curWeapon != kModernThingEnemyLifeLeech) {
}
else if (dist < 12264 && dist > 7680 && !spriteIsUnderwater(pSprite, false) && curWeapon != kModernThingEnemyLifeLeech)
{
int pHit = HitScan(pSprite, pSprite->z, dx, dy, 0, 16777280, 0);
switch (pHit) {
case 0:
@ -601,18 +608,21 @@ static void unicultThinkChase(DBloodActor* actor)
XSPRITE* pXLeech = &xsprite[pLeech->extra];
int ldist = aiFightGetTargetDist(pTarget, pDudeInfo, pLeech);
if (ldist > 3 || !cansee(pTarget->x, pTarget->y, pTarget->z, pTarget->sectnum,
pLeech->x, pLeech->y, pLeech->z, pLeech->sectnum) || pXLeech->target_i == -1) {
pLeech->x, pLeech->y, pLeech->z, pLeech->sectnum) || pXLeech->target_i == -1)
{
aiGenDudeNewState(pSprite, &genDudeThrow2);
genDudeThrow2.nextState = &genDudeDodgeShortL;
} else {
}
else
{
genDudeThrow2.nextState = &genDudeChaseL;
if (dist > 5072 && Chance(0x5000)) {
if (dist > 5072 && Chance(0x5000))
{
if (!canDuck(pSprite) || Chance(0x4000)) aiGenDudeNewState(pSprite, &genDudeDodgeShortL);
else aiGenDudeNewState(pSprite, &genDudeDodgeShortD);
} else {
}
else
{
aiGenDudeNewState(pSprite, &genDudeChaseL);
}
@ -628,9 +638,11 @@ static void unicultThinkChase(DBloodActor* actor)
return;
}
} else if (dist <= meleeVector->maxDist) {
} else if (dist <= meleeVector->maxDist)
{
if (spriteIsUnderwater(pSprite, false)) {
if (spriteIsUnderwater(pSprite, false))
{
if (Chance(0x9000)) aiGenDudeNewState(pSprite, &genDudePunch);
else aiGenDudeNewState(pSprite, &genDudeDodgeW);
@ -639,10 +651,13 @@ static void unicultThinkChase(DBloodActor* actor)
else aiGenDudeNewState(pSprite, &genDudeDodgeL);
return;
} else {
}
else
{
int state = checkAttackState(&bloodActors[pXSprite->reference]);
if (state == 1) aiGenDudeNewState(pSprite, &genDudeChaseW);
else if (state == 2) {
else if (state == 2)
{
if (Chance(0x5000)) aiGenDudeNewState(pSprite, &genDudeChaseD);
else aiGenDudeNewState(pSprite, &genDudeChaseL);
}
@ -650,18 +665,20 @@ static void unicultThinkChase(DBloodActor* actor)
return;
}
}
} else {
}
else
{
int vdist; int mdist; int defDist;
defDist = vdist = mdist = actor->genDudeExtra().fireDist;
if (weaponType == kGenDudeWeaponHitscan) {
if (weaponType == kGenDudeWeaponHitscan)
{
if ((vdist = gVectorData[curWeapon].maxDist) <= 0)
vdist = defDist;
} else if (weaponType == kGenDudeWeaponSummon) {
}
else if (weaponType == kGenDudeWeaponSummon)
{
// don't attack slaves
if (actor->GetTarget() != nullptr && actor->GetTarget()->GetOwner() == actor)
{
@ -674,7 +691,9 @@ static void unicultThinkChase(DBloodActor* actor)
{
aiGenDudeNewState(pSprite, &genDudePunch);
return;
} else {
}
else
{
int state = checkAttackState(&bloodActors[pXSprite->reference]);
if (state == 1) aiGenDudeNewState(pSprite, &genDudeChaseW);
else if (state == 2) aiGenDudeNewState(pSprite, &genDudeChaseD);
@ -683,10 +702,13 @@ static void unicultThinkChase(DBloodActor* actor)
}
}
} else if (weaponType == kGenDudeWeaponMissile) {
}
else if (weaponType == kGenDudeWeaponMissile)
{
// special handling for flame, explosive and life leech missiles
int state = checkAttackState(&bloodActors[pXSprite->reference]);
switch (curWeapon) {
switch (curWeapon)
{
case kMissileLifeLeechRegular:
// pickup life leech if it was thrown previously
if (pLeech != NULL) removeLeech(pLeech);
@ -710,12 +732,15 @@ static void unicultThinkChase(DBloodActor* actor)
case kMissileFlameSpray:
case kMissileFlameHound:
//viewSetSystemMessage("%d", pXTarget->burnTime);
if (spriteIsUnderwater(pSprite, false)) {
if (spriteIsUnderwater(pSprite, false))
{
if (dist > meleeVector->maxDist) aiGenDudeNewState(pSprite, &genDudeChaseW);
else if (Chance(0x8000)) aiGenDudeNewState(pSprite, &genDudePunch);
else aiGenDudeNewState(pSprite, &genDudeDodgeShortW);
return;
} else if (dist <= 4000 && pXTarget->burnTime >= 2000 && pXTarget->burnSource == pSprite->index) {
}
else if (dist <= 4000 && pXTarget->burnTime >= 2000 && pXTarget->burnSource == pSprite->index)
{
if (dist > meleeVector->maxDist) aiGenDudeNewState(pSprite, &genDudeChaseL);
else aiGenDudeNewState(pSprite, &genDudePunch);
return;
@ -723,7 +748,9 @@ static void unicultThinkChase(DBloodActor* actor)
vdist = 3500 + (gGameOptions.nDifficulty * 400);
break;
}
} else if (weaponType == kGenDudeWeaponKamikaze) {
}
else if (weaponType == kGenDudeWeaponKamikaze)
{
int nType = curWeapon - kTrapExploder; const EXPLOSION* pExpl = &explodeInfo[nType];
if (CheckProximity(pSprite, pTarget->x, pTarget->y, pTarget->z, pTarget->sectnum, pExpl->radius >> 1)) {
xvel[pSprite->index] = zvel[pSprite->index] = yvel[pSprite->index] = 0;
@ -736,15 +763,18 @@ static void unicultThinkChase(DBloodActor* actor)
int state = checkAttackState(&bloodActors[pXSprite->reference]);
int kAngle = (dudeIsMelee(pXSprite) || dist <= kGenDudeMaxMeleeDist) ? pDudeInfo->periphery : kGenDudeKlabsAng;
if (dist < vdist && abs(losAngle) < kAngle) {
if (pExtra->canWalk) {
if (dist < vdist && abs(losAngle) < kAngle)
{
if (pExtra->canWalk)
{
int objDist = -1; int targetDist = -1; int hit = -1;
if (weaponType == kGenDudeWeaponHitscan)
hit = HitScan(pSprite, pSprite->z, CosScale16(pSprite->ang), SinScale16(pSprite->ang), actor->dudeSlope, CLIPMASK1, dist);
else if (weaponType == kGenDudeWeaponMissile)
hit = HitScan(pSprite, pSprite->z, CosScale16(pSprite->ang), SinScale16(pSprite->ang), actor->dudeSlope, CLIPMASK0, dist);
if (hit >= 0) {
if (hit >= 0)
{
targetDist = dist - (pTarget->clipdist << 2);
objDist = approxDist(gHitInfo.hitx - pSprite->x, gHitInfo.hity - pSprite->y);
}
@ -782,10 +812,10 @@ static void unicultThinkChase(DBloodActor* actor)
switch (hit) {
case 0:
//if (hit == 0) viewSetSystemMessage("WALL HIT %d", gHitInfo.hitwall);
fallthrough__;
[[fallthrough]];
case 1:
//if (hit == 1) viewSetSystemMessage("CEIL HIT %d", gHitInfo.hitsect);
fallthrough__;
[[fallthrough]];
case 2:
//if (hit == 2) viewSetSystemMessage("FLOOR HIT %d", gHitInfo.hitsect);
if (weaponType != kGenDudeWeaponMissile && genDudeAdjustSlope(actor, dist, weaponType)
@ -797,10 +827,13 @@ static void unicultThinkChase(DBloodActor* actor)
case 3:
if (pHSprite->statnum == kStatFX || pHSprite->statnum == kStatProjectile || pHSprite->statnum == kStatDebris)
break;
if (IsDudeSprite(pHSprite) && (weaponType != kGenDudeWeaponHitscan || hscn)) {
if (IsDudeSprite(pHSprite) && (weaponType != kGenDudeWeaponHitscan || hscn))
{
// dodge a bit in sides
if (pXHSprite->target_i != pSprite->index) {
if (pExtra->baseDispersion < 1024 && weaponType != kGenDudeWeaponMissile) {
if (pXHSprite->target_i != pSprite->index)
{
if (pExtra->baseDispersion < 1024 && weaponType != kGenDudeWeaponMissile)
{
if (spriteIsUnderwater(pSprite)) aiGenDudeNewState(pSprite, &genDudeDodgeShorterW);
else if (inDuck(pXSprite->aiState)) aiGenDudeNewState(pSprite, &genDudeDodgeShorterD);
else aiGenDudeNewState(pSprite, &genDudeDodgeShorterL);
@ -809,16 +842,20 @@ static void unicultThinkChase(DBloodActor* actor)
else if (inDuck(pXSprite->aiState)) aiGenDudeNewState(pSprite, &genDudeDodgeShortD);
else aiGenDudeNewState(pSprite, &genDudeDodgeShortL);
switch (pHSprite->type) {
switch (pHSprite->type)
{
case kDudeModernCustom: // and make dude which could be hit to dodge too
if (!dudeIsMelee(pXHSprite) && Chance(dist << 4)) {
if (!inAttack(pXHSprite->aiState)) {
if (!dudeIsMelee(pXHSprite) && Chance(dist << 4))
{
if (!inAttack(pXHSprite->aiState))
{
if (spriteIsUnderwater(pHSprite)) aiGenDudeNewState(pHSprite, &genDudeDodgeShorterW);
else if (inDuck(pXSprite->aiState)) aiGenDudeNewState(pHSprite, &genDudeDodgeShorterD);
else aiGenDudeNewState(pHSprite, &genDudeDodgeShorterL);
// preferable in opposite sides
if (Chance(0x8000)) {
if (Chance(0x8000))
{
if (pXSprite->dodgeDir == 1) pXHSprite->dodgeDir = -1;
else if (pXSprite->dodgeDir == -1) pXHSprite->dodgeDir = 1;
}
@ -874,28 +911,35 @@ static void unicultThinkChase(DBloodActor* actor)
int wd1 = picWidth(pHSprite->picnum, pHSprite->xrepeat);
int wd2 = picWidth(pSprite->picnum, pSprite->xrepeat);
if (wd1 < (wd2 << 3)) {
if (wd1 < (wd2 << 3))
{
//viewSetSystemMessage("OBJ SIZE: %d DUDE SIZE: %d", wd1, wd2);
if (spriteIsUnderwater(pSprite)) aiGenDudeNewState(pSprite, &genDudeDodgeShorterW);
else if (inDuck(pXSprite->aiState)) aiGenDudeNewState(pSprite, &genDudeDodgeShorterD);
else aiGenDudeNewState(pSprite, &genDudeDodgeShorterL);
if (pSprite->x < pHSprite->x) {
if (pSprite->x < pHSprite->x)
{
if (Chance(0x3000) && pTarget->x > pHSprite->x) pXSprite->dodgeDir = -1;
else pXSprite->dodgeDir = 1;
} else {
}
else
{
if (Chance(0x3000) && pTarget->x > pHSprite->x) pXSprite->dodgeDir = 1;
else pXSprite->dodgeDir = -1;
}
if (((gSpriteHit[pSprite->extra].hit & 0xc000) == 0x8000) || ((gSpriteHit[pSprite->extra].hit & 0xc000) == 0xc000)) {
if (((gSpriteHit[pSprite->extra].hit & 0xc000) == 0x8000) || ((gSpriteHit[pSprite->extra].hit & 0xc000) == 0xc000))
{
if (spriteIsUnderwater(pSprite)) aiGenDudeNewState(pSprite, &genDudeChaseW);
else aiGenDudeNewState(pSprite, &genDudeChaseL);
pXSprite->goalAng = Random(kAng360);
//viewSetSystemMessage("WALL OR SPRITE TOUCH");
}
} else {
}
else
{
if (spriteIsUnderwater(pSprite)) aiGenDudeNewState(pSprite, &genDudeChaseW);
else aiGenDudeNewState(pSprite, &genDudeChaseL);
//viewSetSystemMessage("TOO BIG OBJECT TO DODGE!!!!!!!!");
@ -904,9 +948,10 @@ static void unicultThinkChase(DBloodActor* actor)
}
break;
}
fallthrough__;
[[fallthrough]];
case 4:
if (hit == 4 && weaponType == kGenDudeWeaponHitscan && hscn) {
if (hit == 4 && weaponType == kGenDudeWeaponHitscan && hscn)
{
bool masked = (pHWall->cstat & CSTAT_WALL_MASKED);
if (masked) VectorScan(pSprite, 0, 0, CosScale16(pSprite->ang), SinScale16(pSprite->ang), actor->dudeSlope, dist, 1);
@ -917,7 +962,9 @@ static void unicultThinkChase(DBloodActor* actor)
else aiGenDudeNewState(pSprite, &genDudeChaseL);
return;
}
} else if (hit >= 3 && weaponType == kGenDudeWeaponMissile && blck) {
}
else if (hit >= 3 && weaponType == kGenDudeWeaponMissile && blck)
{
switch (curWeapon) {
case kMissileLifeLeechRegular:
case kMissileTeslaAlt:
@ -925,33 +972,40 @@ static void unicultThinkChase(DBloodActor* actor)
case kMissileFireball:
case kMissileFireballNapalm:
case kMissileFireballCerberus:
case kMissileFireballTchernobog: {
case kMissileFireballTchernobog:
{
// allow attack if dude is far from object, but target is close to it
int dudeDist = approxDist(gHitInfo.hitx - pSprite->x, gHitInfo.hity - pSprite->y);
int targetDist = approxDist(gHitInfo.hitx - pTarget->x, gHitInfo.hity - pTarget->y);
if (dudeDist < mdist) {
if (dudeDist < mdist)
{
//viewSetSystemMessage("DUDE CLOSE TO OBJ: %d, MDIST: %d", dudeDist, mdist);
if (spriteIsUnderwater(pSprite)) aiGenDudeNewState(pSprite, &genDudeChaseW);
else aiGenDudeNewState(pSprite, &genDudeChaseL);
return;
} else if (targetDist <= mdist >> 1) {
}
else if (targetDist <= mdist >> 1)
{
//viewSetSystemMessage("TARGET CLOSE TO OBJ: %d, MDIST: %d", targetDist, mdist >> 1);
break;
}
fallthrough__;
[[fallthrough]];
}
default:
//viewSetSystemMessage("DEF HIT: %d, MDIST: %d", hit, mdist);
if (hit == 4) failed = (pHWall->type != kWallGib || pXHWall == NULL || !pXHWall->triggerVector || pXHWall->locked);
else if (hit == 3 && (failed = (pHSprite->statnum != kStatThing || pXHSprite == NULL || pXHSprite->locked)) == false) {
else if (hit == 3 && (failed = (pHSprite->statnum != kStatThing || pXHSprite == NULL || pXHSprite->locked)) == false)
{
// check also for damage resistance (all possible damages missile can use)
for (int i = 0; i < kDmgMax; i++) {
for (int i = 0; i < kDmgMax; i++)
{
if (gMissileInfoExtra[curWeapon - kMissileBase].dmgType[i] && (failed = nnExtIsImmune(pHSprite, i)) == false)
break;
}
}
if (failed) {
if (failed)
{
if (spriteIsUnderwater(pSprite)) aiGenDudeNewState(pSprite, &genDudeSearchW);
else aiGenDudeNewState(pSprite, &genDudeSearchL);
return;
@ -965,7 +1019,8 @@ static void unicultThinkChase(DBloodActor* actor)
}
aiSetTarget(actor, actor->GetTarget());
switch (state) {
switch (state)
{
case 1:
aiGenDudeNewState(pSprite, &genDudeFireW);
pXSprite->aiState->nextState = &genDudeFireW;
@ -979,33 +1034,43 @@ static void unicultThinkChase(DBloodActor* actor)
pXSprite->aiState->nextState = &genDudeFireL;
break;
}
} else {
if (seqGetID(3, pSprite->extra) == pXSprite->data2 + ((state < 3) ? 8 : 6)) {
}
else
{
if (seqGetID(3, pSprite->extra) == pXSprite->data2 + ((state < 3) ? 8 : 6))
{
if (state == 1) pXSprite->aiState->nextState = &genDudeChaseW;
else if (state == 2) pXSprite->aiState->nextState = &genDudeChaseD;
else pXSprite->aiState->nextState = &genDudeChaseL;
} else if (state == 1 && pXSprite->aiState != &genDudeChaseW && pXSprite->aiState != &genDudeFireW) {
}
else if (state == 1 && pXSprite->aiState != &genDudeChaseW && pXSprite->aiState != &genDudeFireW)
{
aiGenDudeNewState(pSprite, &genDudeChaseW);
pXSprite->aiState->nextState = &genDudeFireW;
} else if (state == 2 && pXSprite->aiState != &genDudeChaseD && pXSprite->aiState != &genDudeFireD) {
}
else if (state == 2 && pXSprite->aiState != &genDudeChaseD && pXSprite->aiState != &genDudeFireD)
{
aiGenDudeNewState(pSprite, &genDudeChaseD);
pXSprite->aiState->nextState = &genDudeFireD;
} else if (pXSprite->aiState != &genDudeChaseL && pXSprite->aiState != &genDudeFireL) {
}
else if (pXSprite->aiState != &genDudeChaseL && pXSprite->aiState != &genDudeFireL)
{
aiGenDudeNewState(pSprite, &genDudeChaseL);
pXSprite->aiState->nextState = &genDudeFireL;
}
}
}
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
int checkAttackState(DBloodActor* actor)
{
@ -1067,6 +1132,12 @@ int getGenDudeMoveSpeed(spritetype* pSprite,int which, bool mul, bool shift) {
return speed;
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void aiGenDudeMoveForward(DBloodActor* actor)
{
auto pXSprite = &actor->x();
@ -1164,6 +1235,12 @@ void aiGenDudeChooseDirection(spritetype* pSprite, XSPRITE* pXSprite, int a3, in
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void aiGenDudeNewState(spritetype* pSprite, AISTATE* pAIState) {
if (!xspriRangeIsFine(pSprite->extra)) {
Printf(PRINT_HIGH, "!xspriRangeIsFine(pSprite->extra)");