- 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.
This commit is contained in:
Christoph Oelckers 2021-08-28 10:38:36 +02:00
parent ad36916fd3
commit 9433e9bdb1
5 changed files with 79 additions and 53 deletions

View file

@ -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

View file

@ -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;
}

View file

@ -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);

View file

@ -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();
}

View file

@ -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;