mirror of
https://github.com/DrBeef/Raze.git
synced 2025-01-19 07:31:03 +00:00
- several aiFight functions.
This commit is contained in:
parent
ca3d7c9bdf
commit
57c3571555
2 changed files with 63 additions and 63 deletions
|
@ -4846,17 +4846,17 @@ DBloodActor* aiFightGetTargetInRange(DBloodActor* actor, int minDist, int maxDis
|
|||
BloodStatIterator it(kStatDude);
|
||||
while (auto targactor = it.Next())
|
||||
{
|
||||
if (!aiFightDudeCanSeeTarget(actor, pDudeInfo, targactor)) continue;
|
||||
|
||||
auto pTarget = &targactor->s();
|
||||
auto pXTarget = &targactor->x();
|
||||
if (!aiFightDudeCanSeeTarget(pXSprite, pDudeInfo, pTarget)) continue;
|
||||
|
||||
int dist = aiFightGetTargetDist(pSprite, pDudeInfo, pTarget);
|
||||
if (dist < minDist || dist > maxDist) continue;
|
||||
else if (actor->GetTarget() == targactor) return targactor;
|
||||
else if (!targactor->IsDudeActor() || targactor == actor || targactor->IsPlayerActor()) continue;
|
||||
else if (IsBurningDude(pTarget) || !IsKillableDude(pTarget) || pTarget->owner == pSprite->index) continue;
|
||||
else if ((teamMode == 1 && aiFightIsMateOf(pXSprite, pXTarget)) || aiFightMatesHaveSameTarget(pXSprite, pTarget, 1)) continue;
|
||||
else if ((teamMode == 1 && aiFightIsMateOf(pXSprite, pXTarget)) || aiFightMatesHaveSameTarget(actor, targactor, 1)) continue;
|
||||
else if (data == 666 || pXTarget->data1 == data)
|
||||
{
|
||||
if (actor->GetTarget())
|
||||
|
@ -4879,15 +4879,11 @@ DBloodActor* aiFightGetTargetInRange(DBloodActor* actor, int minDist, int maxDis
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
spritetype* aiFightTargetIsPlayer(XSPRITE* pXSprite)
|
||||
DBloodActor* aiFightTargetIsPlayer(DBloodActor* actor)
|
||||
{
|
||||
|
||||
if (pXSprite->target_i >= 0) {
|
||||
if (IsPlayerSprite(&sprite[pXSprite->target_i]))
|
||||
return &sprite[pXSprite->target_i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
auto targ = actor->GetTarget();
|
||||
if (targ && targ->IsPlayerActor()) return targ;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -4896,9 +4892,9 @@ spritetype* aiFightTargetIsPlayer(XSPRITE* pXSprite)
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
spritetype* aiFightGetMateTargets(XSPRITE* pXSprite)
|
||||
DBloodActor* aiFightGetMateTargets(DBloodActor* actor)
|
||||
{
|
||||
auto actor = &bloodActors[pXSprite->reference];
|
||||
auto pXSprite = &actor->x();
|
||||
int rx = pXSprite->rxID;
|
||||
|
||||
for (int i = bucketHead[rx]; i < bucketHead[rx + 1]; i++)
|
||||
|
@ -4912,7 +4908,7 @@ spritetype* aiFightGetMateTargets(XSPRITE* pXSprite)
|
|||
if (mate->GetTarget())
|
||||
{
|
||||
if (!mate->GetTarget()->IsPlayerActor())
|
||||
return &mate->GetTarget()->s();
|
||||
return mate->GetTarget();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4925,20 +4921,21 @@ spritetype* aiFightGetMateTargets(XSPRITE* pXSprite)
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool aiFightMatesHaveSameTarget(XSPRITE* pXLeader, spritetype* pTarget, int allow) {
|
||||
auto actor = &bloodActors[pXLeader->reference];
|
||||
int rx = pXLeader->rxID; spritetype* pMate = NULL; XSPRITE* pXMate = NULL;
|
||||
bool aiFightMatesHaveSameTarget(DBloodActor* leaderactor, DBloodActor* targetactor, int allow)
|
||||
{
|
||||
auto pXLeader = &leaderactor->x();
|
||||
int rx = pXLeader->rxID;
|
||||
|
||||
for (int i = bucketHead[rx]; i < bucketHead[rx + 1]; i++)
|
||||
{
|
||||
if (rxBucket[i].type != OBJ_SPRITE)
|
||||
continue;
|
||||
|
||||
auto mate = rxBucket[i].GetActor();
|
||||
if (!mate || !mate->hasX() || mate == actor || !mate->IsDudeActor())
|
||||
auto mate = rxBucket[i].actor;
|
||||
if (!mate || !mate->hasX() || mate == leaderactor || !mate->IsDudeActor())
|
||||
continue;
|
||||
|
||||
if (&(mate->GetTarget()->s()) == pTarget && allow-- <= 0)
|
||||
if (mate->GetTarget() == targetactor && allow-- <= 0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -4950,8 +4947,12 @@ bool aiFightMatesHaveSameTarget(XSPRITE* pXLeader, spritetype* pTarget, int allo
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool aiFightDudeCanSeeTarget(XSPRITE* pXDude, DUDEINFO* pDudeInfo, spritetype* pTarget) {
|
||||
spritetype* pDude = &sprite[pXDude->reference];
|
||||
bool aiFightDudeCanSeeTarget(DBloodActor* dudeactor, DUDEINFO* pDudeInfo, DBloodActor* targetactor)
|
||||
{
|
||||
auto pDude = &dudeactor->s();
|
||||
auto pXDude = &dudeactor->x();
|
||||
auto pTarget = &targetactor->s();
|
||||
|
||||
int dx = pTarget->x - pDude->x; int dy = pTarget->y - pDude->y;
|
||||
|
||||
// check target
|
||||
|
@ -5000,17 +5001,15 @@ void aiFightActivateDudes(int rx)
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void aiFightFreeTargets(int nSprite) {
|
||||
int nTarget;
|
||||
StatIterator it(kStatDude);
|
||||
while ((nTarget = it.NextIndex()) >= 0)
|
||||
void aiFightFreeTargets(DBloodActor* actor)
|
||||
{
|
||||
BloodStatIterator it(kStatDude);
|
||||
while (auto targetactor = it.Next())
|
||||
{
|
||||
if (!IsDudeSprite(&sprite[nTarget]) || sprite[nTarget].extra < 0) continue;
|
||||
else if (xsprite[sprite[nTarget].extra].target_i == nSprite)
|
||||
aiSetTarget_(&xsprite[sprite[nTarget].extra], sprite[nTarget].x, sprite[nTarget].y, sprite[nTarget].z);
|
||||
if (!targetactor->IsDudeActor() || !targetactor->hasX()) continue;
|
||||
else if (targetactor->GetTarget() == actor)
|
||||
aiSetTarget(targetactor, targetactor->s().x, targetactor->s().y, targetactor->s().z);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -5019,14 +5018,14 @@ void aiFightFreeTargets(int nSprite) {
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void aiFightFreeAllTargets(XSPRITE* pXSource) {
|
||||
if (pXSource->txID <= 0) return;
|
||||
for (int i = bucketHead[pXSource->txID]; i < bucketHead[pXSource->txID + 1]; i++)
|
||||
{
|
||||
if (rxBucket[i].type != OBJ_SPRITE) continue;
|
||||
auto rxactor = rxBucket[i].GetActor();
|
||||
if (rxactor && rxactor->hasX())
|
||||
aiFightFreeTargets(rxactor->s().index);
|
||||
void aiFightFreeAllTargets(DBloodActor* sourceactor)
|
||||
{
|
||||
auto txID = sourceactor->x().txID;
|
||||
if (txID <= 0) return;
|
||||
for (int i = bucketHead[txID]; i < bucketHead[txID + 1]; i++)
|
||||
{
|
||||
if (rxBucket[i].type == OBJ_SPRITE && rxBucket[i].actor && rxBucket[i].actor->hasX())
|
||||
aiFightFreeTargets(rxBucket[i].actor);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5089,7 +5088,7 @@ void aiFightAlarmDudesInSight(spritetype* pSprite, int max) {
|
|||
if (pDude->index == pSprite->index || !IsDudeSprite(pDude) || pDude->extra < 0)
|
||||
continue;
|
||||
pXDude = &xsprite[pDude->extra];
|
||||
if (aiFightDudeCanSeeTarget(pXSprite, pDudeInfo, pDude)) {
|
||||
if (aiFightDudeCanSeeTarget(&bloodActors[pXSprite->reference], pDudeInfo, &bloodActors[nSprite])) {
|
||||
if (pXDude->target_i != -1 || pXDude->rxID > 0)
|
||||
continue;
|
||||
|
||||
|
@ -5557,7 +5556,7 @@ bool modernTypeOperateSprite(int nSprite, spritetype* pSprite, XSPRITE* pXSprite
|
|||
[[fallthrough]];
|
||||
case kCmdRepeat:
|
||||
if (pXSprite->txID <= 0 || !aiFightGetDudesForBattle(pXSprite)) {
|
||||
aiFightFreeAllTargets(pXSprite);
|
||||
aiFightFreeAllTargets(actor);
|
||||
evPostActor(actor, 0, kCmdOff);
|
||||
break;
|
||||
} else {
|
||||
|
@ -6449,7 +6448,7 @@ void useTargetChanger(XSPRITE* pXSource, spritetype* pSprite) {
|
|||
// make current target and all other dudes not attack this dude anymore
|
||||
case kThingBloodBits:
|
||||
case kThingBloodChunks:
|
||||
aiFightFreeTargets(pSprite->index);
|
||||
aiFightFreeTargets(&bloodActors[pSprite->index]);
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
|
@ -6484,9 +6483,11 @@ void useTargetChanger(XSPRITE* pXSource, spritetype* pSprite) {
|
|||
}
|
||||
}
|
||||
|
||||
spritetype* pPlayer = aiFightTargetIsPlayer(pXSprite);
|
||||
auto playeractor = aiFightTargetIsPlayer(actor);
|
||||
// special handling for player(s) if target changer data4 > 2.
|
||||
if (pPlayer != NULL) {
|
||||
if (playeractor != nullptr)
|
||||
{
|
||||
auto pPlayer = &playeractor->s();
|
||||
auto actLeech = leechIsDropped(actor);
|
||||
if (pXSource->data4 == 3) {
|
||||
aiSetTarget_(pXSprite, pSprite->x, pSprite->y, pSprite->z);
|
||||
|
@ -6501,7 +6502,7 @@ void useTargetChanger(XSPRITE* pXSource, spritetype* pSprite) {
|
|||
}
|
||||
|
||||
int maxAlarmDudes = 8 + Random(8);
|
||||
if (pXSprite->target_i > -1 && sprite[pXSprite->target_i].extra > -1 && pPlayer == NULL) {
|
||||
if (pXSprite->target_i > -1 && sprite[pXSprite->target_i].extra > -1 && playeractor == nullptr) {
|
||||
pTarget = &sprite[pXSprite->target_i]; pXTarget = &xsprite[pTarget->extra];
|
||||
|
||||
if (aiFightUnitCanFly(pSprite) && aiFightIsMeleeUnit(pTarget) && !aiFightUnitCanFly(pTarget))
|
||||
|
@ -6509,7 +6510,7 @@ void useTargetChanger(XSPRITE* pXSource, spritetype* pSprite) {
|
|||
else if (aiFightUnitCanFly(pSprite))
|
||||
pSprite->flags &= ~0x0002;
|
||||
|
||||
if (!IsDudeSprite(pTarget) || pXTarget->health < 1 || !aiFightDudeCanSeeTarget(pXSprite, pDudeInfo, pTarget)) {
|
||||
if (!IsDudeSprite(pTarget) || pXTarget->health < 1 || !aiFightDudeCanSeeTarget(actor, pDudeInfo, &bloodActors[pTarget->index])) {
|
||||
aiSetTarget_(pXSprite, pSprite->x, pSprite->y, pSprite->z);
|
||||
}
|
||||
// dude attack or attacked by target that does not fit by data id?
|
||||
|
@ -6566,7 +6567,8 @@ void useTargetChanger(XSPRITE* pXSource, spritetype* pSprite) {
|
|||
|
||||
}
|
||||
// check if targets aims player then force this target to fight with dude
|
||||
else if (aiFightTargetIsPlayer(pXTarget) != NULL) {
|
||||
else if (aiFightTargetIsPlayer(actor) != nullptr)
|
||||
{
|
||||
aiSetTarget_(pXTarget, pSprite->index);
|
||||
}
|
||||
|
||||
|
@ -6608,7 +6610,7 @@ void useTargetChanger(XSPRITE* pXSource, spritetype* pSprite) {
|
|||
}
|
||||
}
|
||||
|
||||
if ((pXSprite->target_i < 0 || pPlayer != NULL) && (PlayClock & 32) != 0) {
|
||||
if ((pXSprite->target_i < 0 || playeractor != nullptr) && (PlayClock & 32) != 0) {
|
||||
// try find first target that dude can see
|
||||
int nSprite;
|
||||
StatIterator it(kStatDude);
|
||||
|
@ -6624,14 +6626,15 @@ void useTargetChanger(XSPRITE* pXSource, spritetype* pSprite) {
|
|||
// skip non-dudes and players
|
||||
if (!IsDudeSprite(pTarget) || (IsPlayerSprite(pTarget) && pXSource->data4 > 0) || pTarget->owner == pSprite->index) continue;
|
||||
// avoid self aiming, those who dude can't see, and those who dude own
|
||||
else if (!aiFightDudeCanSeeTarget(pXSprite, pDudeInfo, pTarget) || pSprite->index == pTarget->index) continue;
|
||||
else if (!aiFightDudeCanSeeTarget(actor, pDudeInfo, &bloodActors[pTarget->index]) || pSprite->index == pTarget->index) continue;
|
||||
// if Target Changer have data1 = 666, everyone can be target, except AI team mates.
|
||||
else if (pXSource->data1 != 666 && pXSource->data1 != pXTarget->data1) continue;
|
||||
// don't attack immortal, burning dudes and mates
|
||||
if (IsBurningDude(pTarget) || !IsKillableDude(pTarget) || (pXSource->data2 == 1 && aiFightIsMateOf(pXSprite, pXTarget)))
|
||||
continue;
|
||||
|
||||
if (pXSource->data2 == 0 || (pXSource->data2 == 1 && !aiFightMatesHaveSameTarget(pXSprite, pTarget, matesPerEnemy))) {
|
||||
if (pXSource->data2 == 0 || (pXSource->data2 == 1 && !aiFightMatesHaveSameTarget(&bloodActors[pXSprite->reference], &bloodActors[pTarget->index], matesPerEnemy)))
|
||||
{
|
||||
|
||||
// Change target for dude
|
||||
aiSetTarget_(pXSprite, pTarget->index);
|
||||
|
@ -6641,7 +6644,7 @@ void useTargetChanger(XSPRITE* pXSource, spritetype* pSprite) {
|
|||
// ...and change target of target to dude to force it fight
|
||||
if (pXSource->data3 > 0 && pXTarget->target_i != pSprite->index) {
|
||||
aiSetTarget_(pXTarget, pSprite->index);
|
||||
if (pPlayer == NULL && !isActive(pTarget->index))
|
||||
if (playeractor == NULL && !isActive(pTarget->index))
|
||||
aiActivateDude(&bloodActors[pXTarget->reference]);
|
||||
|
||||
if (pXSource->data3 == 2)
|
||||
|
@ -6656,11 +6659,13 @@ void useTargetChanger(XSPRITE* pXSource, spritetype* pSprite) {
|
|||
}
|
||||
|
||||
// got no target - let's ask mates if they have targets
|
||||
if ((pXSprite->target_i < 0 || pPlayer != NULL) && pXSource->data2 == 1 && (PlayClock & 64) != 0) {
|
||||
spritetype* pMateTarget = NULL;
|
||||
if ((pMateTarget = aiFightGetMateTargets(pXSprite)) != NULL && pMateTarget->extra > 0) {
|
||||
XSPRITE* pXMateTarget = &xsprite[pMateTarget->extra];
|
||||
if (aiFightDudeCanSeeTarget(pXSprite, pDudeInfo, pMateTarget)) {
|
||||
if ((pXSprite->target_i < 0 || playeractor != NULL) && pXSource->data2 == 1 && (PlayClock & 64) != 0) {
|
||||
DBloodActor* pMateTargetActor = aiFightGetMateTargets(actor);
|
||||
if (pMateTargetActor != nullptr && pMateTargetActor->hasX())
|
||||
{
|
||||
auto pMateTarget = &pMateTargetActor->s();
|
||||
XSPRITE* pXMateTarget = &pMateTargetActor->x();
|
||||
if (aiFightDudeCanSeeTarget(actor, pDudeInfo, pMateTargetActor)) {
|
||||
if (pXMateTarget->target_i < 0) {
|
||||
aiSetTarget_(pXMateTarget, pSprite->index);
|
||||
if (IsDudeSprite(pMateTarget) && !isActive(pMateTarget->index))
|
||||
|
@ -6673,7 +6678,7 @@ void useTargetChanger(XSPRITE* pXSource, spritetype* pSprite) {
|
|||
return;
|
||||
|
||||
// try walk in mate direction in case if not see the target
|
||||
} else if (pXMateTarget->target_i >= 0 && aiFightDudeCanSeeTarget(pXSprite, pDudeInfo, &sprite[pXMateTarget->target_i])) {
|
||||
} else if (pXMateTarget->target_i >= 0 && aiFightDudeCanSeeTarget(actor, pDudeInfo, &bloodActors[pXMateTarget->target_i])) {
|
||||
spritetype* pMate = &sprite[pXMateTarget->target_i];
|
||||
pXSprite->target_i = pMateTarget->index;
|
||||
pXSprite->targetX = pMate->x;
|
||||
|
|
|
@ -314,20 +314,15 @@ void aiSetGenIdleState(DBloodActor*);
|
|||
// ------------------------------------------------------------------------- //
|
||||
int aiFightGetTargetDist(spritetype* pSprite, DUDEINFO* pDudeInfo, spritetype* pTarget);
|
||||
int aiFightGetFineTargetDist(spritetype* pSprite, spritetype* pTarget);
|
||||
bool aiFightDudeCanSeeTarget(XSPRITE* pXDude, DUDEINFO* pDudeInfo, spritetype* pTarget);
|
||||
bool aiFightDudeCanSeeTarget(DBloodActor* pXDude, DUDEINFO* pDudeInfo, DBloodActor* pTarget);
|
||||
bool aiFightUnitCanFly(spritetype* pDude);
|
||||
bool aiFightIsMeleeUnit(spritetype* pDude);
|
||||
bool aiFightDudeIsAffected(XSPRITE* pXDude);
|
||||
bool aiFightMatesHaveSameTarget(XSPRITE* pXLeader, spritetype* pTarget, int allow);
|
||||
bool aiFightMatesHaveSameTarget(DBloodActor* leaderactor, DBloodActor* targetactor, int allow);
|
||||
bool aiFightGetDudesForBattle(XSPRITE* pXSprite);
|
||||
bool aiFightIsMateOf(XSPRITE* pXDude, XSPRITE* pXSprite);
|
||||
void aiFightAlarmDudesInSight(spritetype* pSprite, int max);
|
||||
void aiFightActivateDudes(int rx);
|
||||
void aiFightFreeTargets(int nSprite);
|
||||
void aiFightFreeAllTargets(XSPRITE* pXSource);
|
||||
spritetype* aiFightGetTargetInRange(spritetype* pSprite, int minDist, int maxDist, short data, short teamMode);
|
||||
spritetype* aiFightTargetIsPlayer(XSPRITE* pXSprite);
|
||||
spritetype* aiFightGetMateTargets(XSPRITE* pXSprite);
|
||||
// ------------------------------------------------------------------------- //
|
||||
void useSlopeChanger(XSPRITE* pXSource, int objType, int objIndex);
|
||||
void damageSprites(DBloodActor* pXSource, DBloodActor* pSprite);
|
||||
|
|
Loading…
Reference in a new issue