diff --git a/source/games/blood/src/actor.h b/source/games/blood/src/actor.h index c54768e05..dd5f9d017 100644 --- a/source/games/blood/src/actor.h +++ b/source/games/blood/src/actor.h @@ -194,6 +194,11 @@ template bool IsDudeSprite(T const * const pSprite) return pSprite->type >= kDudeBase && pSprite->type < kDudeMax; } +template bool IsThingSprite(T const* const pSprite) +{ + return pSprite->type >= kThingBase && pSprite->type < kThingMax; +} + template bool IsItemSprite(T const * const pSprite) { return pSprite->type >= kItemBase && pSprite->type < kItemMax; diff --git a/source/games/blood/src/aiunicult.cpp b/source/games/blood/src/aiunicult.cpp index 3704dbc8e..03b5ae704 100644 --- a/source/games/blood/src/aiunicult.cpp +++ b/source/games/blood/src/aiunicult.cpp @@ -1278,37 +1278,15 @@ void aiGenDudeNewState(DBloodActor* actor, AISTATE* pAIState) bool playGenDudeSound(DBloodActor* actor, int mode) { - if (mode < kGenDudeSndTargetSpot || mode >= kGenDudeSndMax) return false; - const GENDUDESND* sndInfo = &gCustomDudeSnd[mode]; bool gotSnd = false; + if (mode < kGenDudeSndTargetSpot || mode >= kGenDudeSndMax || !actor->hasX()) return false; + const GENDUDESND* sndInfo = &gCustomDudeSnd[mode]; int sndStartId = actor->xspr.sysData1; int rand = sndInfo->randomRange; int sndId = (sndStartId <= 0) ? sndInfo->defaultSndId : sndStartId + sndInfo->sndIdOffset; GENDUDEEXTRA* pExtra = &actor->genDudeExtra; - // let's check if there same sounds already played by other dudes - // so we won't get a lot of annoying screams in the same time and ensure sound played in it's full length (if not interruptable) - if (pExtra->sndPlaying && !sndInfo->interruptable) { -#if 0 - for (int i = 0; i < 256; i++) { - if (Bonkle[i].atc <= 0) continue; - for (int a = 0; a < rand; a++) { - if (sndId + a == Bonkle[i].atc) { - if (Bonkle[i].at0 <= 0) { - pExtra->sndPlaying = false; - break; - } - return true; - } - } - } -#endif - - pExtra->sndPlaying = false; - - } - if (sndId < 0) return false; - else if (sndStartId <= 0) { sndId += Random(rand); gotSnd = true; } + else if (sndStartId <= 0) sndId += Random(rand); else { // Let's try to get random snd @@ -1317,26 +1295,31 @@ bool playGenDudeSound(DBloodActor* actor, int mode) int random = Random(rand); if (!soundEngine->FindSoundByResID(sndId + random)) continue; sndId = sndId + random; - gotSnd = true; break; } // If no success in getting random snd, get first existing one - if (gotSnd == false) + if (maxRetries <= 0) { int maxSndId = sndId + rand; - while (sndId++ < maxSndId) - { - if (!soundEngine->FindSoundByResID(sndId)) continue; - gotSnd = true; - break; - } + while (sndId < maxSndId && !soundEngine->FindSoundByResID(sndId++)); } + // let's check if there same sounds already played by other dudes + // so we won't get a lot of annoying screams in the same time and + // ensure sound played in it's full length (if not interruptable) + if (pExtra->sndPlaying && !sndInfo->interruptable) + { + if (soundEngine->GetSoundPlayingInfo(SOURCE_Any, nullptr, soundEngine->FindSoundByResID(sndId))) + { + return true; + } + + pExtra->sndPlaying = false; + } } - if (gotSnd == false) return false; - else if (sndInfo->aiPlaySound) aiPlay3DSound(actor, sndId, AI_SFX_PRIORITY_2, -1); + if (sndInfo->aiPlaySound) aiPlay3DSound(actor, sndId, AI_SFX_PRIORITY_2, -1); else sfxPlay3DSound(actor, sndId, -1, 0); pExtra->sndPlaying = true; diff --git a/source/games/blood/src/bloodactor.h b/source/games/blood/src/bloodactor.h index 189c01dbc..6bae0a595 100644 --- a/source/games/blood/src/bloodactor.h +++ b/source/games/blood/src/bloodactor.h @@ -103,6 +103,11 @@ public: return spr.type >= kDudeBase && spr.type < kDudeMax; } + bool IsThingActor() + { + return spr.type >= kThingBase && spr.type < kThingMax; + } + bool IsItemActor() { return spr.type >= kItemBase && spr.type < kItemMax; diff --git a/source/games/blood/src/db.cpp b/source/games/blood/src/db.cpp index cebc28f38..802fbde19 100644 --- a/source/games/blood/src/db.cpp +++ b/source/games/blood/src/db.cpp @@ -66,7 +66,7 @@ int DeleteSprite(DBloodActor* actor) } -bool gModernMap = false; +uint8_t gModernMap = 0; int gVisibility; //--------------------------------------------------------------------------- @@ -172,7 +172,17 @@ void dbLoadMap(const char* pPath, DVector3& pos, short* pAngle, sectortype** cur // indicate if the map requires modern features to work properly // for maps wich created in PMAPEDIT BETA13 or higher versions. Since only minor version changed, // the map is still can be loaded with vanilla BLOOD / MAPEDIT and should work in other ports too. - if ((header.version & 0x00ff) == 0x001) gModernMap = true; + int tmp = (header.version & 0x00ff); + + // get the modern features revision + switch (tmp) { + case 0x001: + gModernMap = 1; + break; + case 0x002: + gModernMap = 2; + break; + } #endif } @@ -579,8 +589,18 @@ void dbLoadMap(const char* pPath, DVector3& pos, short* pAngle, sectortype** cur #ifdef NOONE_EXTENSIONS // indicate if the map requires modern features to work properly // for maps wich created in different editors (include vanilla MAPEDIT) or in PMAPEDIT version below than BETA13 - if (!gModernMap && pXSprite->rxID == kChannelMapModernize && pXSprite->rxID == pXSprite->txID && pXSprite->command == kCmdModernFeaturesEnable) - gModernMap = true; + if (!gModernMap && pXSprite->rxID == pXSprite->txID && pXSprite->command == kCmdModernFeaturesEnable) + { + // get the modern features revision + switch (pXSprite->txID) { + case kChannelMapModernRev1: + gModernMap = 1; + break; + case kChannelMapModernRev2: + gModernMap = 2; + break; + } + } #endif } } diff --git a/source/games/blood/src/eventq.h b/source/games/blood/src/eventq.h index 2711ab622..c767b9de1 100644 --- a/source/games/blood/src/eventq.h +++ b/source/games/blood/src/eventq.h @@ -100,7 +100,8 @@ enum { // channel of event causer kChannelEventCauser = 50, // map requires modern features to work properly - kChannelMapModernize = 60, + kChannelMapModernRev1 = 60, + kChannelMapModernRev2 = 61, ///////////////////////////// kChannelTeamAFlagCaptured = 80, kChannelTeamBFlagCaptured, diff --git a/source/games/blood/src/nnexts.cpp b/source/games/blood/src/nnexts.cpp index d6bb6ac34..d5b47120d 100644 --- a/source/games/blood/src/nnexts.cpp +++ b/source/games/blood/src/nnexts.cpp @@ -4802,7 +4802,7 @@ bool condCheckSprite(DBloodActor* aCond, int cmpOp, bool PUSH) // //--------------------------------------------------------------------------- -void condUpdateObjectIndex(DBloodActor* oldActor, DBloodActor* newActor) +void conditionsUpdateIndex(DBloodActor* oldActor, DBloodActor* newActor) { // update index in tracking conditions first for (int i = 0; i < gTrackingCondsCount; i++) diff --git a/source/games/blood/src/nnexts.h b/source/games/blood/src/nnexts.h index be8edaa55..dfe816798 100644 --- a/source/games/blood/src/nnexts.h +++ b/source/games/blood/src/nnexts.h @@ -265,7 +265,7 @@ struct CONDITION_TYPE_NAMES { }; // - VARIABLES ------------------------------------------------------------------ -extern bool gModernMap; +extern uint8_t gModernMap; extern bool gTeamsSpawnUsed; extern bool gEventRedirectsUsed; extern ZONE gStartZoneTeam1[kMaxPlayers]; @@ -372,7 +372,7 @@ void levelEndLevelCustom(int nLevel); int useCondition(DBloodActor*, EVENT& event); bool condCmp(int val, int arg1, int arg2, int comOp); void condError(DBloodActor* pXCond, const char* pzFormat, ...); -void condUpdateObjectIndex(DBloodActor* oldplayer, DBloodActor* newplayer); +void conditionsUpdateIndex(DBloodActor* oldplayer, DBloodActor* newplayer); DBloodActor* evrListRedirectors(int objType, sectortype*, walltype*, DBloodActor* objActor, DBloodActor* pXRedir, int* tx); void seqSpawnerOffSameTx(DBloodActor* actor); void triggerTouchSprite(DBloodActor* pSprite, DBloodActor* nHSprite); diff --git a/source/games/blood/src/player.cpp b/source/games/blood/src/player.cpp index 280e35baf..4e63ef992 100644 --- a/source/games/blood/src/player.cpp +++ b/source/games/blood/src/player.cpp @@ -883,12 +883,12 @@ void playerStart(int nPlayer, int bNewLevel) BloodStatIterator it(kStatModernPlayerLinker); while (auto iactor = it.Next()) { - if (iactor->xspr.data1 == pPlayer->nPlayer + 1) + if (!iactor->xspr.data1 || iactor->xspr.data1 == pPlayer->nPlayer + 1) { DBloodActor* SpriteOld = iactor->prevmarker; trPlayerCtrlLink(iactor, pPlayer, (SpriteOld == nullptr)); // this modifies iactor's prevmarker field! if (SpriteOld) - condUpdateObjectIndex(SpriteOld, iactor->prevmarker); + conditionsUpdateIndex(SpriteOld, iactor->prevmarker); } }