diff --git a/source/games/blood/src/eventq.cpp b/source/games/blood/src/eventq.cpp index 96412bfe0..b37d6e590 100644 --- a/source/games/blood/src/eventq.cpp +++ b/source/games/blood/src/eventq.cpp @@ -577,14 +577,14 @@ void evKillActor(DBloodActor* actor, CALLBACK_ID cb) evKill_(actor, 0, SS_SPRITE, cb); } -void evKillWall(int wal) +void evKillWall(walltype* wal) { - evKill_(nullptr, wal, SS_WALL); + evKill_(nullptr, wallnum(wal), SS_WALL); } -void evKillSector(int sec) +void evKillSector(sectortype* sec) { - evKill_(nullptr, sec, SS_SECTOR); + evKill_(nullptr, sectnum(sec), SS_SECTOR); } // these have no target. diff --git a/source/games/blood/src/eventq.h b/source/games/blood/src/eventq.h index b27f996ba..10ea33440 100644 --- a/source/games/blood/src/eventq.h +++ b/source/games/blood/src/eventq.h @@ -198,6 +198,39 @@ struct EVENT { return (this->type == type && (this->type != SS_SPRITE ? (this->index_ == index) : (this->actor == actor))); } + + bool isActor() const + { + return type == SS_SPRITE; + } + + bool isSector() const + { + return type == SS_SECTOR; + } + + bool isWall() const + { + return type == SS_WALL; + } + + DBloodActor* getActor() const + { + assert(isActor()); + return actor; + } + + sectortype* getSector() const + { + assert(isSector()); + return §or[index_]; + } + + walltype* getWall() const + { + assert(isWall()); + return &wall[index_]; + } }; void evInit(void); diff --git a/source/games/blood/src/nnexts.cpp b/source/games/blood/src/nnexts.cpp index 45d706219..7d0534ad0 100644 --- a/source/games/blood/src/nnexts.cpp +++ b/source/games/blood/src/nnexts.cpp @@ -4769,9 +4769,11 @@ void modernTypeSendCommand(DBloodActor* actor, int destChannel, COMMAND_ID comma void modernTypeTrigger(int destObjType, int destObjIndex, DBloodActor* destactor, const EVENT& event) { - if (event.type != OBJ_SPRITE || !event.actor || !event.actor->hasX()) return; - spritetype* pSource = &event.actor->s(); - XSPRITE* pXSource = &event.actor->x(); + if (!event.isActor()) return; + auto pActor = event.getActor(); + if (!pActor || !pActor->hasX()) return; + spritetype* pSource = &pActor->s(); + XSPRITE* pXSource = &pActor->x(); switch (destObjType) { case OBJ_SECTOR: @@ -4803,14 +4805,14 @@ void modernTypeTrigger(int destObjType, int destObjIndex, DBloodActor* destactor case kModernSequentialTX: if (pSpr->flags & kModernTypeFlag1) { - seqTxSendCmdAll(destactor, event.actor, (COMMAND_ID)pXSource->command, true); + seqTxSendCmdAll(destactor, pActor, (COMMAND_ID)pXSource->command, true); return; } useSequentialTx(destactor, (COMMAND_ID)pXSource->command, false); // set next TX id break; } if (pXSpr->txID <= 0 || pXSpr->txID >= kChannelUserMax) return; - modernTypeSendCommand(event.actor, pXSpr->txID, (COMMAND_ID)pXSource->command); + modernTypeSendCommand(pActor, pXSpr->txID, (COMMAND_ID)pXSource->command); return; } break; @@ -4824,7 +4826,7 @@ void modernTypeTrigger(int destObjType, int destObjIndex, DBloodActor* destactor // allows teleport any sprite from any location to the source destination case kMarkerWarpDest: if (destObjType != OBJ_SPRITE) break; - useTeleportTarget(event.actor, destactor); + useTeleportTarget(pActor, destactor); break; // changes slope of sprite or sector case kModernSlopeChanger: @@ -4832,7 +4834,7 @@ void modernTypeTrigger(int destObjType, int destObjIndex, DBloodActor* destactor { case OBJ_SPRITE: case OBJ_SECTOR: - useSlopeChanger(event.actor, destObjType, destObjIndex, destactor); + useSlopeChanger(pActor, destObjType, destObjIndex, destactor); break; } break; @@ -4842,73 +4844,73 @@ void modernTypeTrigger(int destObjType, int destObjIndex, DBloodActor* destactor { case OBJ_SPRITE: case OBJ_SECTOR: - useSpriteDamager(event.actor, destObjType, destObjIndex, destactor); + useSpriteDamager(pActor, destObjType, destObjIndex, destactor); break; } break; // can spawn any effect passed in data2 on it's or txID sprite case kModernEffectSpawner: if (destObjType != OBJ_SPRITE) break; - useEffectGen(event.actor, destactor); + useEffectGen(pActor, destactor); break; // takes data2 as SEQ ID and spawns it on it's or TX ID object case kModernSeqSpawner: - useSeqSpawnerGen(event.actor, destObjType, destObjIndex, destactor); + useSeqSpawnerGen(pActor, destObjType, destObjIndex, destactor); break; // creates wind on TX ID sector case kModernWindGenerator: if (destObjType != OBJ_SECTOR || pXSource->data2 < 0) break; - useSectorWindGen(event.actor, §or[destObjIndex]); + useSectorWindGen(pActor, §or[destObjIndex]); break; // size and pan changer of sprite/wall/sector via TX ID case kModernObjSizeChanger: - useObjResizer(event.actor, destObjType, destObjIndex, destactor); + useObjResizer(pActor, destObjType, destObjIndex, destactor); break; // iterate data filed value of destination object case kModernObjDataAccumulator: - useIncDecGen(event.actor, destObjType, destObjIndex, destactor); + useIncDecGen(pActor, destObjType, destObjIndex, destactor); break; // change data field value of destination object case kModernObjDataChanger: - useDataChanger(event.actor, destObjType, destObjIndex, destactor); + useDataChanger(pActor, destObjType, destObjIndex, destactor); break; // change sector lighting dynamically case kModernSectorFXChanger: if (destObjType != OBJ_SECTOR) break; - useSectorLightChanger(event.actor, §or[destObjIndex]); + useSectorLightChanger(pActor, §or[destObjIndex]); break; // change target of dudes and make it fight case kModernDudeTargetChanger: if (destObjType != OBJ_SPRITE) break; - useTargetChanger(event.actor, destactor); + useTargetChanger(pActor, destactor); break; // change picture and palette of TX ID object case kModernObjPicnumChanger: - usePictureChanger(event.actor, destObjType, destObjIndex, destactor); + usePictureChanger(pActor, destObjType, destObjIndex, destactor); break; // change various properties case kModernObjPropertiesChanger: - usePropertiesChanger(event.actor, destObjType, destObjIndex, destactor); + usePropertiesChanger(pActor, destObjType, destObjIndex, destactor); break; // updated vanilla sound gen that now allows to play sounds on TX ID sprites case kGenModernSound: if (destObjType != OBJ_SPRITE) break; - useSoundGen(event.actor, destactor); + useSoundGen(pActor, destactor); break; // updated ecto skull gen that allows to fire missile from TX ID sprites case kGenModernMissileUniversal: if (destObjType != OBJ_SPRITE) break; - useUniMissileGen(event.actor, destactor); + useUniMissileGen(pActor, destactor); break; // spawn enemies on TX ID sprites case kMarkerDudeSpawn: if (destObjType != OBJ_SPRITE) break; - useDudeSpawn(event.actor, destactor); + useDudeSpawn(pActor, destactor); break; // spawn custom dude on TX ID sprites case kModernCustomDudeSpawn: if (destObjType != OBJ_SPRITE) break; - useCustomDudeSpawn(event.actor, destactor); + useCustomDudeSpawn(pActor, destactor); break; } } @@ -5301,11 +5303,12 @@ void sectorKillSounds(int nSector) void sectorPauseMotion(int nSector) { - if (!sector[nSector].hasX()) return; - XSECTOR* pXSector = §or[nSector].xs(); + auto pSector = §or[nSector]; + if (!pSector->hasX()) return; + XSECTOR* pXSector = &pSector->xs(); pXSector->unused1 = 1; - evKillSector(nSector); + evKillSector(pSector); sectorKillSounds(nSector); if ((pXSector->busy == 0 && !pXSector->state) || (pXSector->busy == 65536 && pXSector->state)) @@ -5500,7 +5503,7 @@ void useDudeSpawn(DBloodActor* pSource, DBloodActor* pSprite) // //--------------------------------------------------------------------------- -bool modernTypeOperateSprite(DBloodActor* actor, EVENT event) +bool modernTypeOperateSprite(DBloodActor* actor, const EVENT& event) { auto pSprite = &actor->s(); auto pXSprite = &actor->x(); @@ -5533,21 +5536,24 @@ bool modernTypeOperateSprite(DBloodActor* actor, EVENT event) } else if (event.cmd == kCmdDudeFlagsSet) { - if (event.type != OBJ_SPRITE) + if (!event.isActor()) { viewSetSystemMessage("Only sprites can use command #%d", event.cmd); return true; } - else if (event.actor && event.actor->hasX()) - { - - // copy dude flags from the source to destination sprite - aiPatrolFlagsMgr(event.actor, actor, true, false); - } + else + { + auto pEvActor = event.getActor(); + if (pEvActor && pEvActor->hasX()) + { - } + // copy dude flags from the source to destination sprite + aiPatrolFlagsMgr(pEvActor, actor, true, false); + } + } + } if (pSprite->statnum == kStatDude && actor->IsDudeActor()) { switch (event.cmd) @@ -5571,8 +5577,12 @@ bool modernTypeOperateSprite(DBloodActor* actor, EVENT event) break; case kCmdDudeFlagsSet: - if (!event.actor || !event.actor->hasX()) break; - else aiPatrolFlagsMgr(event.actor, actor, false, true); // initialize patrol dude with possible new flags + if (event.isActor()) + { + auto pEvActor = event.getActor(); + if (!pEvActor || !pEvActor->hasX()) break; + else aiPatrolFlagsMgr(pEvActor, actor, false, true); // initialize patrol dude with possible new flags + } break; default: @@ -6204,24 +6214,28 @@ int useCondition(DBloodActor* sourceactor, const EVENT& event) spritetype* pSource = &sourceactor->s(); auto pXSource = &sourceactor->x(); - int objType = event.type; - int objIndex = event.index_; bool srcIsCondition = false; - if (objType == OBJ_SPRITE && event.actor == nullptr) return -1; - if (objType == OBJ_SPRITE && event.actor != sourceactor) - srcIsCondition = (event.actor->s().type == kModernCondition || event.actor->s().type == kModernConditionFalse); + + int objType = event.isActor() ? SS_SPRITE : event.isSector() ? SS_SECTOR : SS_WALL; + int objIndex = event.isActor() ? -1 : event.isSector() ? sectnum(event.getSector()) : wallnum(event.getWall()); + auto pActor = event.isActor() ? event.getActor() : nullptr; + + + if (event.isActor() && pActor == nullptr) return -1; + if (event.isActor() && pActor != sourceactor) + srcIsCondition = (pActor->s().type == kModernCondition || pActor->s().type == kModernConditionFalse); // if it's a tracking condition, it must ignore all the commands sent from objects if (pXSource->busyTime > 0 && event.funcID != kCallbackMax) return -1; else if (!srcIsCondition) // save object serials in the stack and make copy of initial object { - condPush(sourceactor, objType, objIndex, event.actor); + condPush(sourceactor, objType, objIndex, pActor); condBackup(sourceactor); } else // or grab serials of objects from previous conditions { - sourceactor->condition[0] = event.actor->condition[0]; - sourceactor->condition[1] = event.actor->condition[1]; + sourceactor->condition[0] = pActor->condition[0]; + sourceactor->condition[1] = pActor->condition[1]; } @@ -6279,7 +6293,7 @@ int useCondition(DBloodActor* sourceactor, const EVENT& event) // send it for object currently in the focus if (pSource->flags & kModernTypeFlag1) { - nnExtTriggerObject(objType, objIndex, event.actor, pXSource->command); + nnExtTriggerObject(objType, objIndex, pActor, pXSource->command); } // send it for initial object diff --git a/source/games/blood/src/nnexts.h b/source/games/blood/src/nnexts.h index 927bccea1..39888d9af 100644 --- a/source/games/blood/src/nnexts.h +++ b/source/games/blood/src/nnexts.h @@ -335,7 +335,7 @@ void trPlayerCtrlStopScene(PLAYER* pPlayer); // ------------------------------------------------------------------------- // void modernTypeTrigger(int type, int nDest, DBloodActor* actor, const EVENT& event); bool modernTypeOperateSector(int nSector, sectortype* pSector, XSECTOR* pXSector, const EVENT& event); -bool modernTypeOperateSprite(DBloodActor*, EVENT event); +bool modernTypeOperateSprite(DBloodActor*, const EVENT& event); bool modernTypeOperateWall(int nWall, walltype* pWall, XWALL* pXWall, EVENT event); void modernTypeSendCommand(DBloodActor* nSprite, int channel, COMMAND_ID command); // ------------------------------------------------------------------------- // diff --git a/source/games/blood/src/triggers.cpp b/source/games/blood/src/triggers.cpp index 7ec7a0711..3546332a6 100644 --- a/source/games/blood/src/triggers.cpp +++ b/source/games/blood/src/triggers.cpp @@ -82,7 +82,7 @@ bool SetWallState(walltype* pWall, int nState) return 0; pXWall->busy = IntToFixed(nState); pXWall->state = nState; - evKillWall(wallnum(pWall)); + evKillWall(pWall); if (pXWall->restState != nState && pXWall->waitTime > 0) evPostWall(pWall, (pXWall->waitTime*120) / 10, pXWall->restState ? kCmdOn : kCmdOff); if (pXWall->txID) @@ -102,7 +102,7 @@ bool SetSectorState(int nSector, XSECTOR *pXSector, int nState) return 0; pXSector->busy = IntToFixed(nState); pXSector->state = nState; - evKillSector(nSector); + evKillSector(pSector); if (nState == 1) { if (pXSector->command != kCmdLink && pXSector->triggerOn && pXSector->txID) @@ -167,25 +167,22 @@ void ReverseBusy(int a1, BUSYID a2) } } -unsigned int GetSourceBusy(EVENT a1) +unsigned int GetSourceBusy(const EVENT& a1) { - int nIndex = a1.index_; - switch (a1.type) + if (a1.isSector()) { - case 6: - { - auto sect = §or[nIndex]; + auto sect = a1.getSector(); return sect->hasX()? sect->xs().busy : 0; } - case 0: + else if (a1.isWall()) { - auto wal = &wall[nIndex]; + auto wal = a1.getWall(); return wal->hasX()? wal->xw().busy : 0; } - case 3: + else if (a1.isActor()) { - return a1.actor && a1.actor->hasX() ? a1.actor->x().busy : false; - } + auto pActor = a1.getActor(); + return pActor && pActor->hasX() ? pActor->x().busy : false; } return 0; } @@ -1686,9 +1683,9 @@ void LinkSprite(DBloodActor* actor, EVENT event) switch (pSprite->type) { case kSwitchCombo: { - if (event.type == OBJ_SPRITE) + if (event.isActor()) { - auto actor2 = event.actor; + auto actor2 = event.getActor(); pXSprite->data1 = actor2 && actor2->hasX()? actor2->x().data1 : 0; if (pXSprite->data1 == pXSprite->data2)