- 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 #ifdef NOONE_EXTENSIONS
case kDudeModernCustom: 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)) if (pExtra->canElectrocute && pDudeExtra->teslaHit && !spriteIsUnderwater(pSprite, false))
{ {

View file

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