From 9433e9bdb14bdbe42be28e06404691e392c6edef Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 28 Aug 2021 10:38:36 +0200 Subject: [PATCH] - trPlayerCtrlStartScene + changing index to initiator pointer in QAVSCENE. - clear QAVSCENE's initiator pointer at the start of a level or when it holds an actor that's about to be deleted. Seems there is no proper bookkeeping here, so until we can GC actors it needs to be done manually. --- source/games/blood/src/db.cpp | 9 ++- source/games/blood/src/nnexts.cpp | 114 ++++++++++++++++++------------ source/games/blood/src/nnexts.h | 5 +- source/games/blood/src/player.cpp | 2 +- source/games/blood/src/weapon.cpp | 2 +- 5 files changed, 79 insertions(+), 53 deletions(-) diff --git a/source/games/blood/src/db.cpp b/source/games/blood/src/db.cpp index 7cd922347..40b6caf79 100644 --- a/source/games/blood/src/db.cpp +++ b/source/games/blood/src/db.cpp @@ -227,7 +227,9 @@ int DeleteSprite(int nSprite) assert(sprite[nSprite].sectnum >= 0 && sprite[nSprite].sectnum < kMaxSectors); RemoveSpriteSect(nSprite); InsertSpriteStat(nSprite, kMaxStatus); - +#ifdef NOONE_EXTENSIONS + for (auto& ctrl : gPlayerCtrl) if (ctrl.qavScene.initiator == &bloodActors[nSprite]) ctrl.qavScene.initiator = nullptr; +#endif Numsprites--; return nSprite; @@ -520,6 +522,11 @@ void dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, shor memset(wall, 0, sizeof(*wall) * MAXWALLS); memset(sprite, 0, sizeof(*sector) * MAXSPRITES); +#ifdef NOONE_EXTENSIONS + for (auto& ctrl : gPlayerCtrl) ctrl.qavScene.initiator = nullptr; +#endif + + #ifdef USE_OPENGL Polymost::Polymost_prepare_loadboard(); #endif diff --git a/source/games/blood/src/nnexts.cpp b/source/games/blood/src/nnexts.cpp index 94bda211e..1df4a8d68 100644 --- a/source/games/blood/src/nnexts.cpp +++ b/source/games/blood/src/nnexts.cpp @@ -2055,29 +2055,35 @@ void windGenStopWindOnSectors(DBloodActor* sourceactor) } } +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- -void trPlayerCtrlStartScene(XSPRITE* pXSource, PLAYER* pPlayer, bool force) { +void trPlayerCtrlStartScene(DBloodActor* sourceactor, PLAYER* pPlayer, bool force) +{ + auto pXSource = &sourceactor->x(); + TRPLAYERCTRL* pCtrl = &gPlayerCtrl[pPlayer->nPlayer]; - int nSource = pXSource->reference; TRPLAYERCTRL* pCtrl = &gPlayerCtrl[pPlayer->nPlayer]; - - if (pCtrl->qavScene.index >= 0 && !force) return; + if (pCtrl->qavScene.initiator != nullptr && !force) return; QAV* pQav = playerQavSceneLoad(pXSource->data2); - if (pQav != NULL) { - + if (pQav != nullptr) + { // save current weapon pXSource->dropMsg = pPlayer->curWeapon; - short nIndex = pCtrl->qavScene.index; - if (nIndex > -1 && nIndex != nSource && sprite[nIndex].extra >= 0) - pXSource->dropMsg = xsprite[sprite[nIndex].extra].dropMsg; + auto initiator = pCtrl->qavScene.initiator; + if (initiator != nullptr && initiator != sourceactor && initiator->hasX()) + pXSource->dropMsg = initiator->x().dropMsg; - if (nIndex < 0) + if (initiator == nullptr) WeaponLower(pPlayer); pXSource->sysData1 = ClipLow((pQav->duration * pXSource->waitTime) / 4, 0); // how many times animation should be played - pCtrl->qavScene.index = nSource; + pCtrl->qavScene.initiator = sourceactor; pCtrl->qavScene.qavResrc = pQav; pCtrl->qavScene.dummy = -1; @@ -2089,27 +2095,35 @@ void trPlayerCtrlStartScene(XSPRITE* pXSource, PLAYER* pPlayer, bool force) { pPlayer->qavLoop = false; pPlayer->qavLastTick = I_GetTime(pCtrl->qavScene.qavResrc->ticrate); pPlayer->qavTimer = pCtrl->qavScene.qavResrc->duration; - } - } -void trPlayerCtrlStopScene(PLAYER* pPlayer) { +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- +void trPlayerCtrlStopScene(PLAYER* pPlayer) +{ TRPLAYERCTRL* pCtrl = &gPlayerCtrl[pPlayer->nPlayer]; - int scnIndex = pCtrl->qavScene.index; XSPRITE* pXSource = NULL; - if (spriRangeIsFine(scnIndex)) { - pXSource = &xsprite[sprite[scnIndex].extra]; + auto initiator = pCtrl->qavScene.initiator; + XSPRITE* pXSource = nullptr; + if (initiator->hasX()) + { + pXSource = &initiator->x(); pXSource->sysData1 = 0; } - if (pCtrl->qavScene.index >= 0) { - pCtrl->qavScene.index = -1; - pCtrl->qavScene.qavResrc = NULL; + if (pCtrl->qavScene.initiator != nullptr) + { + pCtrl->qavScene.initiator = nullptr; + pCtrl->qavScene.qavResrc = nullptr; pPlayer->sceneQav = -1; // restore weapon - if (pPlayer->pXSprite->health > 0) { + if (pPlayer->pXSprite->health > 0) + { int oldWeapon = (pXSource && pXSource->dropMsg != 0) ? pXSource->dropMsg : 1; pPlayer->newWeapon = pPlayer->curWeapon = oldWeapon; WeaponRaise(pPlayer); @@ -2414,13 +2428,16 @@ void trPlayerCtrlGiveStuff(XSPRITE* pXSource, PLAYER* pPlayer, TRPLAYERCTRL* pCt } break; } - if (pPlayer->hasWeapon[weapon] && pXSource->data4 == 0) { // switch on it + if (pPlayer->hasWeapon[weapon] && pXSource->data4 == 0) // switch on it + { pPlayer->nextWeapon = kWeapNone; - if (pPlayer->sceneQav >= 0 && spriRangeIsFine(pCtrl->qavScene.index)) { - XSPRITE* pXScene = &xsprite[sprite[pCtrl->qavScene.index].extra]; - pXScene->dropMsg = weapon; - } else if (pPlayer->curWeapon != weapon) { + if (pPlayer->sceneQav >= 0 && pCtrl->qavScene.initiator && pCtrl->qavScene.initiator->hasX()) + { + pCtrl->qavScene.initiator->x().dropMsg = weapon; + } + else if (pPlayer->curWeapon != weapon) + { pPlayer->newWeapon = weapon; WeaponRaise(pPlayer); } @@ -5534,7 +5551,7 @@ bool modernTypeOperateSprite(int nSprite, spritetype* pSprite, XSPRITE* pXSprite else trPlayerCtrlSetScreenEffect(pXSprite, pPlayer); break; case 3: // 67 (start playing qav scene) - trPlayerCtrlStartScene(pXSprite, pPlayer, (pXSprite->data4 == 1) ? true : false); + trPlayerCtrlStartScene(actor, pPlayer, (pXSprite->data4 == 1) ? true : false); break; case 4: // 68 (stop playing qav scene) if (pXSprite->data2 > 0 && pXSprite->data2 != pPlayer->sceneQav) break; @@ -6588,27 +6605,28 @@ QAV* playerQavSceneLoad(int qavId) { return pQav; } -void playerQavSceneProcess(PLAYER* pPlayer, QAVSCENE* pQavScene) { - int nIndex = pQavScene->index; - auto qavactor = &bloodActors[nIndex]; - if (qavactor->hasX()) { - - XSPRITE* pXSprite = &xsprite[sprite[nIndex].extra]; +void playerQavSceneProcess(PLAYER* pPlayer, QAVSCENE* pQavScene) +{ + auto initiator = pQavScene->initiator; + if (initiator->hasX()) + { + XSPRITE* pXSprite = &initiator->x(); if (pXSprite->waitTime > 0 && --pXSprite->sysData1 <= 0) { if (pXSprite->txID >= kChannelUser) { - XSPRITE* pXSpr = NULL; - for (int i = bucketHead[pXSprite->txID]; i < bucketHead[pXSprite->txID + 1]; i++) { - if (rxBucket[i].type == OBJ_SPRITE) { - + for (int i = bucketHead[pXSprite->txID]; i < bucketHead[pXSprite->txID + 1]; i++) + { + if (rxBucket[i].type == OBJ_SPRITE) + { auto rxactor = rxBucket[i].GetActor(); - if (!rxactor || !rxactor->hasX() || rxactor == qavactor) continue; - spritetype* pSpr = &rxactor->s(); + if (!rxactor || !rxactor->hasX() || rxactor == initiator) continue; - pXSpr = &xsprite[pSpr->extra]; - if (pSpr->type == kModernPlayerControl && pXSpr->command == 67) { + spritetype* pSpr = &rxactor->s(); + auto pXSpr = &rxactor->x(); + if (pSpr->type == kModernPlayerControl && pXSpr->command == 67) + { if (pXSpr->data2 == pXSprite->data2 || pXSpr->locked) continue; - else trPlayerCtrlStartScene(pXSpr, pPlayer, true); + else trPlayerCtrlStartScene(rxactor, pPlayer, true); return; } nnExtTriggerObject(rxBucket[i].type, rxactor->s().index, pXSprite->command); @@ -6631,7 +6649,8 @@ void playerQavSceneProcess(PLAYER* pPlayer, QAVSCENE* pQavScene) { } } else { - pQavScene->index = pPlayer->sceneQav = -1; + pQavScene->initiator = nullptr; + pPlayer->sceneQav = -1; pQavScene->qavResrc = NULL; } } @@ -6640,7 +6659,7 @@ void playerQavSceneDraw(PLAYER* pPlayer, int a2, double a3, double a4, int a5) { if (pPlayer == NULL || pPlayer->sceneQav == -1) return; QAVSCENE* pQavScene = &gPlayerCtrl[pPlayer->nPlayer].qavScene; - spritetype* pSprite = &sprite[pQavScene->index]; + spritetype* pSprite = &pQavScene->initiator->s(); if (pQavScene->qavResrc != NULL) { @@ -6676,8 +6695,8 @@ void playerQavScenePlay(PLAYER* pPlayer) { if (pPlayer == NULL) return; QAVSCENE* pQavScene = &gPlayerCtrl[pPlayer->nPlayer].qavScene; - if (pPlayer->sceneQav == -1 && pQavScene->index >= 0) - pPlayer->sceneQav = xsprite[sprite[pQavScene->index].extra].data2; + if (pPlayer->sceneQav == -1 && pQavScene->initiator != nullptr) + pPlayer->sceneQav = pQavScene->initiator->x().data2; if (pQavScene->qavResrc != NULL) { QAV* pQAV = pQavScene->qavResrc; @@ -6689,7 +6708,8 @@ void playerQavScenePlay(PLAYER* pPlayer) { void playerQavSceneReset(PLAYER* pPlayer) { QAVSCENE* pQavScene = &gPlayerCtrl[pPlayer->nPlayer].qavScene; - pQavScene->index = pQavScene->dummy = pPlayer->sceneQav = -1; + pQavScene->initiator = nullptr; + pQavScene->dummy = pPlayer->sceneQav = -1; pQavScene->qavResrc = NULL; } diff --git a/source/games/blood/src/nnexts.h b/source/games/blood/src/nnexts.h index 3ed8501ed..f87421ac3 100644 --- a/source/games/blood/src/nnexts.h +++ b/source/games/blood/src/nnexts.h @@ -199,8 +199,8 @@ struct SPRITEMASS { // sprite mass info for getSpriteMassBySize(); }; struct QAVSCENE { // this one stores qavs anims that can be played by trigger - short index = -1; // index of sprite which triggered qav scene - QAV* qavResrc = NULL; + DBloodActor* initiator = nullptr; // index of sprite which triggered qav scene + QAV* qavResrc = nullptr; short dummy = -1; }; @@ -354,7 +354,6 @@ void seqTxSendCmdAll(XSPRITE* pXSource, int nIndex, COMMAND_ID cmd, bool modernS // ------------------------------------------------------------------------- // void trPlayerCtrlLink(XSPRITE* pXSource, PLAYER* pPlayer, bool checkCondition); void trPlayerCtrlSetRace(XSPRITE* pXSource, PLAYER* pPlayer); -void trPlayerCtrlStartScene(XSPRITE* pXSource, PLAYER* pPlayer, bool force); void trPlayerCtrlStopScene(PLAYER* pPlayer); void trPlayerCtrlSetMoveSpeed(XSPRITE* pXSource, PLAYER* pPlayer); void trPlayerCtrlSetJumpHeight(XSPRITE* pXSource, PLAYER* pPlayer); diff --git a/source/games/blood/src/player.cpp b/source/games/blood/src/player.cpp index 74e315ad3..5658c2dab 100644 --- a/source/games/blood/src/player.cpp +++ b/source/games/blood/src/player.cpp @@ -2355,7 +2355,7 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, TRPLAYERCTRL& w, T { if (arc.BeginObject(keyname)) { - arc("index", w.qavScene.index) + arc("index", w.qavScene.initiator) ("dummy", w.qavScene.dummy) .EndObject(); } diff --git a/source/games/blood/src/weapon.cpp b/source/games/blood/src/weapon.cpp index 3a2c66e30..4507d02cf 100644 --- a/source/games/blood/src/weapon.cpp +++ b/source/games/blood/src/weapon.cpp @@ -2031,7 +2031,7 @@ void WeaponProcess(PLAYER *pPlayer) { pPlayer->flashEffect = ClipLow(pPlayer->flashEffect - 1, 0); #ifdef NOONE_EXTENSIONS - if (gPlayerCtrl[pPlayer->nPlayer].qavScene.index >= 0 && pPlayer->pXSprite->health > 0) { + if (gPlayerCtrl[pPlayer->nPlayer].qavScene.initiator != nullptr && pPlayer->pXSprite->health > 0) { playerQavSceneProcess(pPlayer, &gPlayerCtrl[pPlayer->nPlayer].qavScene); UpdateAimVector(pPlayer); return;