diff --git a/source/games/blood/src/actor.cpp b/source/games/blood/src/actor.cpp index f6c6aa621..5f2012a22 100644 --- a/source/games/blood/src/actor.cpp +++ b/source/games/blood/src/actor.cpp @@ -6423,14 +6423,52 @@ DBloodActor* actSpawnSprite(int nSector, int x, int y, int z, int nStat, bool se // //--------------------------------------------------------------------------- -spritetype *actSpawnDude(spritetype *pSource, short nType, int a3, int a4) +DBloodActor* actSpawnSprite(DBloodActor* source, int nStat) { - XSPRITE* pXSource = &xsprite[pSource->extra]; - spritetype *pSprite2 = actSpawnSprite(pSource, kStatDude); - if (!pSprite2) return NULL; - XSPRITE *pXSprite2 = &xsprite[pSprite2->extra]; + auto pSource = &source->s(); + int nSprite = InsertSprite(pSource->sectnum, nStat); + if (nSprite < 0) + { + StatIterator it(kStatPurge); + nSprite = it.NextIndex(); + assert(nSprite >= 0); + assert(pSource->sectnum >= 0 && pSource->sectnum < kMaxSectors); + ChangeSpriteSect(nSprite, pSource->sectnum); + actPostSprite(nSprite, nStat); + } + auto actor = &bloodActors[nSprite]; + + spritetype* pSprite = &actor->s(); + pSprite->x = pSource->x; + pSprite->y = pSource->y; + pSprite->z = pSource->z; + actor->xvel() = source->xvel(); + actor->yvel() = source->yvel(); + actor->zvel() = source->zvel(); + pSprite->flags = 0; + actor->addX(); + actor->hit().florhit = 0; + actor->hit().ceilhit = 0; + if (!VanillaMode()) actor->SetTarget(nullptr); + return actor; +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +DBloodActor* actSpawnDude(DBloodActor* source, short nType, int a3, int a4) +{ + auto pSource = &source->s(); + XSPRITE* pXSource = &source->x(); + auto spawned = actSpawnSprite(source, kStatDude); + if (!spawned) return NULL; + spritetype* pSprite2 = &spawned->s(); + XSPRITE* pXSprite2 = &spawned->x(); int angle = pSource->ang; - int nDude = nType-kDudeBase; + int nDude = nType - kDudeBase; int x, y, z; z = a4 + pSource->z; if (a3 < 0) @@ -6440,25 +6478,28 @@ spritetype *actSpawnDude(spritetype *pSource, short nType, int a3, int a4) } else { - x = pSource->x+mulscale30r(Cos(angle), a3); - y = pSource->y+mulscale30r(Sin(angle), a3); + x = pSource->x + mulscale30r(Cos(angle), a3); + y = pSource->y + mulscale30r(Sin(angle), a3); } pSprite2->type = nType; pSprite2->ang = angle; vec3_t pos = { x, y, z }; setsprite(pSprite2->index, &pos); pSprite2->cstat |= 0x1101; - pSprite2->clipdist = getDudeInfo(nDude+kDudeBase)->clipdist; - pXSprite2->health = getDudeInfo(nDude+kDudeBase)->startHealth<<4; + pSprite2->clipdist = getDudeInfo(nDude + kDudeBase)->clipdist; + pXSprite2->health = getDudeInfo(nDude + kDudeBase)->startHealth << 4; pXSprite2->respawn = 1; - if (getSequence(getDudeInfo(nDude+kDudeBase)->seqStartID)) - seqSpawn(getDudeInfo(nDude+kDudeBase)->seqStartID, 3, pSprite2->extra, -1); - - #ifdef NOONE_EXTENSIONS + if (getSequence(getDudeInfo(nDude + kDudeBase)->seqStartID)) + seqSpawn(getDudeInfo(nDude + kDudeBase)->seqStartID, spawned, -1); + +#ifdef NOONE_EXTENSIONS // add a way to inherit some values of spawner type 18 by dude. // This way designer can count enemies via switches and do many other interesting things. - if (gModernMap && pSource->flags & kModernTypeFlag1) { - switch (pSource->type) { // allow inheriting only for selected source types + if (gModernMap && pSource->flags & kModernTypeFlag1) + { + // allow inheriting only for selected source types + switch (pSource->type) + { case kMarkerDudeSpawn: //inherit pal? if (pSprite2->pal <= 0) pSprite2->pal = pSource->pal; @@ -6481,39 +6522,17 @@ spritetype *actSpawnDude(spritetype *pSource, short nType, int a3, int a4) break; } } - #endif +#endif aiInitSprite(pSprite2); - return pSprite2; + return spawned; } -spritetype * actSpawnSprite(spritetype *pSource, int nStat) -{ - int nSprite = InsertSprite(pSource->sectnum, nStat); - if (nSprite < 0) - { - StatIterator it(kStatPurge); - nSprite = it.NextIndex(); - assert(nSprite >= 0); - assert(pSource->sectnum >= 0 && pSource->sectnum < kMaxSectors); - ChangeSpriteSect(nSprite, pSource->sectnum); - actPostSprite(nSprite, nStat); - } - spritetype *pSprite = &sprite[nSprite]; - pSprite->x = pSource->x; - pSprite->y = pSource->y; - pSprite->z = pSource->z; - xvel[nSprite] = xvel[pSource->index]; - yvel[nSprite] = yvel[pSource->index]; - zvel[nSprite] = zvel[pSource->index]; - pSprite->flags = 0; - int nXSprite = dbInsertXSprite(nSprite); - gSpriteHit[nXSprite].florhit = 0; - gSpriteHit[nXSprite].ceilhit = 0; - if (!VanillaMode()) - xsprite[nXSprite].target = -1; - return pSprite; -} +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- spritetype * actSpawnThing(int nSector, int x, int y, int z, int nThingType) { diff --git a/source/games/blood/src/actor.h b/source/games/blood/src/actor.h index 6bd3b4206..43b136fd8 100644 --- a/source/games/blood/src/actor.h +++ b/source/games/blood/src/actor.h @@ -233,8 +233,8 @@ void actExplodeSprite(DBloodActor *pSprite); void actActivateGibObject(DBloodActor *actor); void actProcessSprites(void); DBloodActor* actSpawnSprite(int nSector, int x, int y, int z, int nStat, bool a6); -spritetype *actSpawnDude(spritetype *pSource, short nType, int a3, int a4); -spritetype * actSpawnSprite(spritetype *pSource, int nStat); +DBloodActor* actSpawnDude(DBloodActor* pSource, short nType, int a3, int a4); +DBloodActor * actSpawnSprite(DBloodActor *pSource, int nStat); spritetype * actSpawnThing(int nSector, int x, int y, int z, int nThingType); spritetype * actFireThing_(spritetype *pSprite, int a2, int a3, int a4, int thingType, int a6); DBloodActor* actFireThing(DBloodActor* pSprite, int a2, int a3, int a4, int thingType, int a6); diff --git a/source/games/blood/src/aispid.cpp b/source/games/blood/src/aispid.cpp index bdf888a7b..3cb13f105 100644 --- a/source/games/blood/src/aispid.cpp +++ b/source/games/blood/src/aispid.cpp @@ -152,19 +152,20 @@ void SpidBirthSeqCallback(int, DBloodActor* actor) int nAngle = getangle(dx, dy); int nDist = approxDist(dx, dy); - spritetype *pSpawn = NULL; - if (IsPlayerSprite(pTarget) && pDudeExtraE->xval2 < 10) { - + DBloodActor* spawned = nullptr; + if (IsPlayerSprite(pTarget) && pDudeExtraE->xval2 < 10) + { if (nDist < 0x1a00 && nDist > 0x1400 && abs(pSprite->ang-nAngle) < pDudeInfo->periphery) - pSpawn = actSpawnDude(pSprite, kDudeSpiderRed, pSprite->clipdist, 0); + spawned = actSpawnDude(actor, kDudeSpiderRed, pSprite->clipdist, 0); else if (nDist < 0x1400 && nDist > 0xc00 && abs(pSprite->ang-nAngle) < pDudeInfo->periphery) - pSpawn = actSpawnDude(pSprite, kDudeSpiderBrown, pSprite->clipdist, 0); + spawned = actSpawnDude(actor, kDudeSpiderBrown, pSprite->clipdist, 0); else if (nDist < 0xc00 && abs(pSprite->ang - nAngle) < pDudeInfo->periphery) - pSpawn = actSpawnDude(pSprite, kDudeSpiderBrown, pSprite->clipdist, 0); - - if (pSpawn) { + spawned = actSpawnDude(actor, kDudeSpiderBrown, pSprite->clipdist, 0); + + if (spawned) + { pDudeExtraE->xval2++; - pSpawn->owner = pSprite->index; + spawned->SetOwner(spawned); gKillMgr.AddNewKill(1); } } diff --git a/source/games/blood/src/aiunicult.cpp b/source/games/blood/src/aiunicult.cpp index ee73a3014..7ce5a6b9f 100644 --- a/source/games/blood/src/aiunicult.cpp +++ b/source/games/blood/src/aiunicult.cpp @@ -232,9 +232,12 @@ void genDudeAttack1(int, DBloodActor* actor) } else if (pExtra->weaponType == kGenDudeWeaponSummon) { - spritetype* pSpawned = NULL; int dist = pSprite->clipdist << 4; + DBloodActor* spawned = nullptr; + int dist = pSprite->clipdist << 4; if (pExtra->slaveCount <= gGameOptions.nDifficulty) { - if ((pSpawned = actSpawnDude(pSprite, pExtra->curWeapon, dist + Random(dist), 0)) != NULL) { + if ((spawned = actSpawnDude(actor, pExtra->curWeapon, dist + Random(dist), 0)) != NULL) + { + spritetype* pSpawned = &spawned->s(); pSpawned->owner = pSprite->index; if (xspriRangeIsFine(pSpawned->extra)) { @@ -1630,8 +1633,11 @@ bool doExplosion(spritetype* pSprite, int nType) // so custom dude can have different weapons, hp and so on... spritetype* genDudeSpawn(XSPRITE* pXSource, spritetype* pSprite, int nDist) { - spritetype* pSource = &sprite[pXSource->reference]; - spritetype* pDude = actSpawnSprite(pSprite, kStatDude); XSPRITE* pXDude = &xsprite[pDude->extra]; + DBloodActor* actor = &bloodActors[pSprite->index]; + spritetype* pSource = &sprite[pXSource->reference]; + auto spawned = actSpawnSprite(actor, kStatDude); + spritetype* pDude = &spawned->s(); + XSPRITE* pXDude = &spawned->x(); int x, y, z = pSprite->z, nAngle = pSprite->ang, nType = kDudeModernCustom; diff --git a/source/games/blood/src/callback.cpp b/source/games/blood/src/callback.cpp index d1243a137..482ce9d58 100644 --- a/source/games/blood/src/callback.cpp +++ b/source/games/blood/src/callback.cpp @@ -25,6 +25,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "build.h" #include "blood.h" +#include "bloodactor.h" BEGIN_BLD_NS @@ -70,12 +71,13 @@ void Remove(int nSprite) // 1 void FlareBurst(int nSprite) // 2 { assert(nSprite >= 0 && nSprite < kMaxSprites); + auto actor = &bloodActors[nSprite]; spritetype *pSprite = &sprite[nSprite]; int nAngle = getangle(xvel[nSprite], yvel[nSprite]); int nRadius = 0x55555; for (int i = 0; i < 8; i++) { - spritetype *pSpawn = actSpawnSprite(pSprite, 5); + spritetype *pSpawn = &actSpawnSprite(actor, 5)->s(); pSpawn->picnum = 2424; pSpawn->shade = -128; pSpawn->xrepeat = pSpawn->yrepeat = 32; diff --git a/source/games/blood/src/nnexts.cpp b/source/games/blood/src/nnexts.cpp index e419aadb5..d7ad0a5c7 100644 --- a/source/games/blood/src/nnexts.cpp +++ b/source/games/blood/src/nnexts.cpp @@ -271,12 +271,13 @@ void nnExResetPatrolBonkles() { spritetype* nnExtSpawnDude(XSPRITE* pXSource, spritetype* pSprite, short nType, int a3, int a4) { - spritetype* pDude = NULL; + DBloodActor* pDudeActor = nullptr; spritetype* pSource = &sprite[pXSource->reference]; - if (nType < kDudeBase || nType >= kDudeMax || (pDude = actSpawnSprite(pSprite, kStatDude)) == NULL) + if (nType < kDudeBase || nType >= kDudeMax || (pDudeActor = actSpawnSprite(&bloodActors[pSprite->index], kStatDude)) == NULL) return NULL; - XSPRITE* pXDude = &xsprite[pDude->extra]; + spritetype* pDude = &pDudeActor->s(); + XSPRITE* pXDude = &pDudeActor->x(); int angle = pSprite->ang; int x, y, z = a4 + pSprite->z; @@ -970,16 +971,12 @@ spritetype* randomDropPickupObject(spritetype* pSource, short prevItem) { } // this function spawns random dude using dudeSpawn -spritetype* randomSpawnDude(XSPRITE* pXSource, spritetype* pSprite, int a3, int a4) { - +spritetype* randomSpawnDude(XSPRITE* pXSource, spritetype* pSprite, int a3, int a4) +{ spritetype* pSprite2 = NULL; int selected = -1; - spritetype* pSource = &sprite[pXSource->reference]; - if (xspriRangeIsFine(pSource->extra)) { - XSPRITE* pXSource = &xsprite[pSource->extra]; - if ((selected = randomGetDataValue(pXSource, kRandomizeDude)) > 0) - pSprite2 = nnExtSpawnDude(pXSource, pSprite, selected, a3, 0); - } + if ((selected = randomGetDataValue(pXSource, kRandomizeDude)) > 0) + pSprite2 = nnExtSpawnDude(pXSource, pSprite, selected, a3, 0); return pSprite2; } @@ -7787,6 +7784,7 @@ void levelEndLevelCustom(int nLevel) { void callbackUniMissileBurst(int nSprite) // 22 { + auto actor = &bloodActors[nSprite]; assert(nSprite >= 0 && nSprite < kMaxSprites); if (sprite[nSprite].statnum != kStatProjectile) return; spritetype* pSprite = &sprite[nSprite]; @@ -7795,7 +7793,7 @@ void callbackUniMissileBurst(int nSprite) // 22 for (int i = 0; i < 8; i++) { - spritetype* pBurst = actSpawnSprite(pSprite, 5); + spritetype* pBurst = &actSpawnSprite(actor, 5)->s(); pBurst->type = pSprite->type; pBurst->shade = pSprite->shade; diff --git a/source/games/blood/src/player.cpp b/source/games/blood/src/player.cpp index 3233f6e71..a834e2bec 100644 --- a/source/games/blood/src/player.cpp +++ b/source/games/blood/src/player.cpp @@ -1570,7 +1570,9 @@ void ProcessInput(PLAYER *pPlayer) pPlayer->handTime = ClipLow(pPlayer->handTime-4*(6-gGameOptions.nDifficulty), 0); if (pPlayer->handTime <= 0 && pPlayer->hand) { - spritetype *pSprite2 = actSpawnDude(pPlayer->pSprite, kDudeHand, pPlayer->pSprite->clipdist<<1, 0); + auto pactor = &bloodActors[pPlayer->pSprite->index]; + auto spawned = actSpawnDude(pactor, kDudeHand, pPlayer->pSprite->clipdist<<1, 0); + spritetype* pSprite2 = &spawned->s(); pSprite2->ang = (pPlayer->pSprite->ang+1024)&2047; int nSprite = pPlayer->pSprite->index; int x = CosScale16(pPlayer->pSprite->ang); diff --git a/source/games/blood/src/triggers.cpp b/source/games/blood/src/triggers.cpp index 28aa333de..8fdcb02c7 100644 --- a/source/games/blood/src/triggers.cpp +++ b/source/games/blood/src/triggers.cpp @@ -456,8 +456,10 @@ void OperateSprite(int nSprite, XSPRITE *pXSprite, EVENT event) break; case kMarkerDudeSpawn: - if (gGameOptions.nMonsterSettings && pXSprite->data1 >= kDudeBase && pXSprite->data1 < kDudeMax) { - spritetype* pSpawn = actSpawnDude(pSprite, pXSprite->data1, -1, 0); + if (gGameOptions.nMonsterSettings && pXSprite->data1 >= kDudeBase && pXSprite->data1 < kDudeMax) + { + auto actor = &bloodActors[pSprite->index]; + spritetype* pSpawn = &actSpawnDude(actor, pXSprite->data1, -1, 0)->s(); if (pSpawn) { XSPRITE *pXSpawn = &xsprite[pSpawn->extra]; gKillMgr.AddNewKill(1);