From d2f16ec8ab2c3d5cd3ed39b0a1abb96f3d78e5b8 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 5 May 2021 21:06:38 +0200 Subject: [PATCH] - leechIsDropped, pLifeLeech --- source/games/blood/src/ai.cpp | 2 +- source/games/blood/src/aiunicult.cpp | 54 ++++++++++++++++------------ source/games/blood/src/aiunicult.h | 4 +-- source/games/blood/src/nnexts.cpp | 29 +++++++++------ 4 files changed, 53 insertions(+), 36 deletions(-) diff --git a/source/games/blood/src/ai.cpp b/source/games/blood/src/ai.cpp index fb322ddd4..cc3f25c01 100644 --- a/source/games/blood/src/ai.cpp +++ b/source/games/blood/src/ai.cpp @@ -1670,7 +1670,7 @@ void aiProcessDudes(void) case kDudeModernCustomBurning: { GENDUDEEXTRA* pExtra = &actor->genDudeExtra(); if (pExtra->slaveCount > 0) updateTargetOfSlaves(pSprite); - if (pExtra->nLifeLeech >= 0) updateTargetOfLeech(pSprite); + if (pExtra->pLifeLeech != nullptr) updateTargetOfLeech(pSprite); if (pXSprite->stateTimer == 0 && pXSprite->aiState && pXSprite->aiState->nextState && (pXSprite->aiState->stateTicks > 0 || seqGetStatus(3, pSprite->extra) < 0)) { diff --git a/source/games/blood/src/aiunicult.cpp b/source/games/blood/src/aiunicult.cpp index 66ee6c1ce..a22311286 100644 --- a/source/games/blood/src/aiunicult.cpp +++ b/source/games/blood/src/aiunicult.cpp @@ -339,8 +339,9 @@ static void ThrowThing(DBloodActor* actor, bool impact) int dz = pTarget->z - pSprite->z; int dist = approxDist(dx, dy); - spritetype* pLeech = leechIsDropped(pSprite); - XSPRITE* pXLeech = (pLeech != NULL) ? &xsprite[pLeech->extra] : NULL; + auto actLeech = leechIsDropped(actor); + spritetype* pLeech = actLeech? &actLeech->s() : nullptr; + XSPRITE* pXLeech = actLeech && actLeech->hasX()? &actLeech->x() : nullptr; switch (curWeapon) { case kModernThingEnemyLifeLeech: @@ -403,7 +404,7 @@ static void ThrowThing(DBloodActor* actor, bool impact) pXSpawned->Proximity = true; pXSpawned->stateTimer = 1; - actor->genDudeExtra().nLifeLeech = pSpawned->index; + actor->genDudeExtra().pLifeLeech = spawned; evPost(spawned, 80, kCallbackLeechStateTimer); return; } @@ -571,7 +572,10 @@ static void unicultThinkChase(DBloodActor* actor) int curWeapon = actor->genDudeExtra().curWeapon; int weaponType = actor->genDudeExtra().weaponType; - spritetype* pLeech = leechIsDropped(pSprite); + + auto actLeech = leechIsDropped(actor); + spritetype* pLeech = actLeech? &actLeech->s() : nullptr; + const VECTORDATA* meleeVector = &gVectorData[22]; if (weaponType == kGenDudeWeaponThrow) { @@ -1407,11 +1411,9 @@ bool spriteIsUnderwater(DBloodActor* actor, bool oldWay) || (oldWay && (pXSprite->medium == kMediumWater || pXSprite->medium == kMediumGoo))); } -spritetype* leechIsDropped(spritetype* pSprite) { - short nLeech = gGenDudeExtra[pSprite->index].nLifeLeech; - if (nLeech >= 0 && nLeech < kMaxSprites) return &sprite[nLeech]; - return NULL; - +DBloodActor* leechIsDropped(DBloodActor* actor) +{ + return actor->genDudeExtra().pLifeLeech; } void removeDudeStuff(spritetype* pSprite) { @@ -1455,7 +1457,7 @@ void removeLeech(spritetype* pLeech, bool delSprite) { sfxPlay3DSoundCP(pLeech, 490, -1, 0,60000); if (pLeech->owner >= 0 && pLeech->owner < kMaxSprites) - gGenDudeExtra[sprite[pLeech->owner].index].nLifeLeech = -1; + gGenDudeExtra[sprite[pLeech->owner].index].pLifeLeech = nullptr; if (delSprite) { pLeech->type = kSpriteDecoration; @@ -1472,7 +1474,7 @@ void killDudeLeech(spritetype* pLeech) { sfxPlay3DSoundCP(pLeech, 522, -1, 0, 60000); if (pLeech->owner >= 0 && pLeech->owner < kMaxSprites) - gGenDudeExtra[sprite[pLeech->owner].index].nLifeLeech = -1; + gGenDudeExtra[sprite[pLeech->owner].index].pLifeLeech = nullptr; } } @@ -2054,17 +2056,25 @@ void updateTargetOfLeech(spritetype* pSprite) { return; } + auto actor = &bloodActors[pSprite->index]; - spritetype* pLeech = leechIsDropped(pSprite); - if (pLeech == NULL || pLeech->extra < 0) gGenDudeExtra[pSprite->index].nLifeLeech = -1; - else if (xsprite[pSprite->extra].target_i != xsprite[pLeech->extra].target_i) { - XSPRITE* pXDude = &xsprite[pSprite->extra]; XSPRITE* pXLeech = &xsprite[pLeech->extra]; - if (pXDude->target_i < 0 && spriRangeIsFine(pXLeech->target_i)) { - aiSetTarget_(pXDude, pXLeech->target_i); + auto actLeech = leechIsDropped(actor); + if (actLeech == NULL || !actLeech->hasX()) actor->genDudeExtra().pLifeLeech = nullptr; + else + { + XSPRITE* pXDude = &actor->x(); + if (actor->GetTarget() != actLeech->GetTarget()) + { + if (actor->GetTarget() == nullptr && actLeech->GetTarget() != nullptr) + { + aiSetTarget(actor, actLeech->GetTarget()); if (inIdle(pXDude->aiState)) - aiActivateDude(&bloodActors[pXDude->reference]); - } else { - pXLeech->target_i = pXDude->target_i; + aiActivateDude(actor); + } + else + { + actLeech->SetTarget(actor->GetTarget()); + } } } } @@ -2367,14 +2377,14 @@ bool genDudePrepare(spritetype* pSprite, int propId) { fallthrough__; } case kGenDudePropertyLeech: - pExtra->nLifeLeech = -1; + pExtra->pLifeLeech = nullptr; if (pSprite->owner != kMaxSprites - 1) { int nSprite; StatIterator it(kStatThing); while ((nSprite = it.NextIndex()) >= 0) { if (sprite[nSprite].owner == pSprite->index && sprite[nSprite].type == kModernThingEnemyLifeLeech) { - pExtra->nLifeLeech = nSprite; + pExtra->pLifeLeech = &bloodActors[nSprite]; break; } } diff --git a/source/games/blood/src/aiunicult.h b/source/games/blood/src/aiunicult.h index 3ebc31e4c..4c0ad419c 100644 --- a/source/games/blood/src/aiunicult.h +++ b/source/games/blood/src/aiunicult.h @@ -169,7 +169,7 @@ struct GENDUDEEXTRA unsigned short baseDispersion; unsigned short slaveCount; // how many dudes is summoned //unsigned short incarnationsCount; - signed short nLifeLeech; // spritenum of dropped dude's leech + DBloodActor* pLifeLeech; // spritenum of dropped dude's leech signed short slave[kGenDudeMaxSlaves]; // index of the ones dude is summon signed short dmgControl[kDamageMax]; // depends of current weapon, drop armor item, sprite yrepeat and surface type bool updReq[kGenDudePropertyMax]; // update requests @@ -199,7 +199,7 @@ XSPRITE* getNextIncarnation(XSPRITE* pXSprite); void killDudeLeech(spritetype* pLeech); void removeLeech(spritetype* pLeech, bool delSprite = true); void removeDudeStuff(spritetype* pSprite); -spritetype* leechIsDropped(spritetype* pSprite); +DBloodActor* leechIsDropped(DBloodActor* pSprite); bool spriteIsUnderwater(DBloodActor* pSprite, bool oldWay = false); bool playGenDudeSound(DBloodActor* actor, int mode); void aiGenDudeMoveForward(DBloodActor* actor); diff --git a/source/games/blood/src/nnexts.cpp b/source/games/blood/src/nnexts.cpp index c3712a1de..d50c90b89 100644 --- a/source/games/blood/src/nnexts.cpp +++ b/source/games/blood/src/nnexts.cpp @@ -3849,15 +3849,20 @@ bool condCheckDude(XSPRITE* pXCond, int cmpOp, bool PUSH) { case kDudeModernCustomBurning: switch (cond) { case 20: // life leech is thrown? - var = actor->genDudeExtra().nLifeLeech; - if (!spriRangeIsFine(var)) return false; - else if (PUSH) condPush(pXCond, OBJ_SPRITE, var); + { + auto act = actor->genDudeExtra().pLifeLeech; + if (!act) return false; + else if (PUSH) condPush(pXCond, OBJ_SPRITE, act->s().index); return true; + } case 21: // life leech is destroyed? - var = actor->genDudeExtra().nLifeLeech; - if (!spriRangeIsFine(var) && pSpr->owner == kMaxSprites - 1) return true; - else if (PUSH) condPush(pXCond, OBJ_SPRITE, var); + { + auto act = actor->genDudeExtra().pLifeLeech; + if (!act) return false; + if (pSpr->owner == kMaxSprites - 1) return true; + else if (PUSH) condPush(pXCond, OBJ_SPRITE, act->s().index); return false; + } case 22: // are required amount of dudes is summoned? return condCmp(gGenDudeExtra[pSpr->index].slaveCount, arg1, arg2, cmpOp); case 23: // check if dude can... @@ -5875,6 +5880,7 @@ void useTargetChanger(XSPRITE* pXSource, spritetype* pSprite) { //spritetype* pSource = &sprite[pXSource->reference]; + auto actor = &bloodActors[pSprite->index]; XSPRITE* pXSprite = &xsprite[pSprite->extra]; spritetype* pTarget = NULL; XSPRITE* pXTarget = NULL; int receiveHp = 33 + Random(33); DUDEINFO* pDudeInfo = getDudeInfo(pSprite->type); int matesPerEnemy = 1; @@ -5902,15 +5908,16 @@ void useTargetChanger(XSPRITE* pXSource, spritetype* pSprite) { spritetype* pPlayer = aiFightTargetIsPlayer(pXSprite); // special handling for player(s) if target changer data4 > 2. if (pPlayer != NULL) { + auto actLeech = leechIsDropped(actor); if (pXSource->data4 == 3) { aiSetTarget_(pXSprite, pSprite->x, pSprite->y, pSprite->z); aiSetGenIdleState(pSprite, pXSprite); - if (pSprite->type == kDudeModernCustom && leechIsDropped(pSprite)) - removeLeech(leechIsDropped(pSprite)); + if (pSprite->type == kDudeModernCustom && actLeech) + removeLeech(&actLeech->s()); } else if (pXSource->data4 == 4) { aiSetTarget_(pXSprite, pPlayer->x, pPlayer->y, pPlayer->z); - if (pSprite->type == kDudeModernCustom && leechIsDropped(pSprite)) - removeLeech(leechIsDropped(pSprite)); + if (pSprite->type == kDudeModernCustom && actLeech) + removeLeech(&actLeech->s()); } } @@ -7907,7 +7914,7 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, GENDUDEEXTRA& w, G ("weapontype", w.weaponType) ("basedispersion", w.baseDispersion) ("slavecount", w.slaveCount) - ("lifeleech", w.nLifeLeech) + ("lifeleech", w.pLifeLeech) .Array("slaves", w.slave, w.slaveCount) .Array("dmgcontrol", w.dmgControl, kDamageMax) .Array("updreq", w.updReq, kGenDudePropertyMax)