From 16d4aebbb4ea8873d50ceb1d987e89f89bc21fba Mon Sep 17 00:00:00 2001 From: Grind Core Date: Sat, 12 Oct 2019 23:45:46 +0300 Subject: [PATCH] - Fixes for refactor - Some ThrowError() calls was replaced my viewSetSystemMessage() - New modern type playQAV (WIP) # Conflicts: # source/blood/src/actor.cpp # source/blood/src/weapon.h --- source/blood/src/actor.cpp | 269 +++++++++++++++------------------ source/blood/src/actor.h | 9 +- source/blood/src/aispid.cpp | 9 +- source/blood/src/asound.cpp | 86 ++++++----- source/blood/src/blood.cpp | 4 + source/blood/src/callback.cpp | 115 +++++++------- source/blood/src/callback.h | 2 +- source/blood/src/common_game.h | 6 +- source/blood/src/endgame.cpp | 53 +++---- source/blood/src/eventq.cpp | 45 +++--- source/blood/src/seq.cpp | 18 ++- source/blood/src/sfx.cpp | 13 +- source/blood/src/tile.cpp | 9 +- source/blood/src/triggers.cpp | 108 +++++++++---- source/blood/src/triggers.h | 1 + source/blood/src/weapon.h | 2 +- 16 files changed, 389 insertions(+), 360 deletions(-) diff --git a/source/blood/src/actor.cpp b/source/blood/src/actor.cpp index 31ff1854b..9ddba578c 100644 --- a/source/blood/src/actor.cpp +++ b/source/blood/src/actor.cpp @@ -2645,41 +2645,37 @@ void actInit(bool bSaveLoad) { } } - for (int nSprite = headspritestat[kStatItem]; nSprite >= 0; nSprite = nextspritestat[nSprite]) - { - spritetype *pSprite = &sprite[nSprite]; - if (pSprite->type == kItemWeaponVoodooDoll) - pSprite->type = kAmmoItemVoodooDoll; - - } - for (int nSprite = headspritestat[kStatTraps]; nSprite >= 0; nSprite = nextspritestat[nSprite]) - { - spritetype *pSprite = &sprite[nSprite]; - int nXSprite = pSprite->extra; - XSPRITE *pXSprite = NULL; - if (nXSprite > 0 && nXSprite < kMaxXSprites) - pXSprite = &xsprite[nXSprite]; - if (pSprite->type == kTrapExploder) { - pXSprite->state = 0; - pXSprite->waitTime = ClipLow(pXSprite->waitTime, 1); - pSprite->cstat &= ~1; - pSprite->cstat |= 32768; + for (int nSprite = headspritestat[kStatItem]; nSprite >= 0; nSprite = nextspritestat[nSprite]) { + switch (sprite[nSprite].type) { + case kItemWeaponVoodooDoll: + sprite[nSprite].type = kAmmoItemVoodooDoll; + break; } } - for (int nSprite = headspritestat[kStatThing]; nSprite >= 0; nSprite = nextspritestat[nSprite]) - { + + for (int nSprite = headspritestat[kStatTraps]; nSprite >= 0; nSprite = nextspritestat[nSprite]) { spritetype *pSprite = &sprite[nSprite]; - int nXSprite = pSprite->extra; - if (nXSprite <= 0 || nXSprite >= kMaxXSprites) - ThrowError("WARNING: Sprite %d is on the wrong status list!\n", nSprite); - XSPRITE *pXSprite = &xsprite[nXSprite]; + switch (pSprite->type) { + case kTrapExploder: + pSprite->cstat &= ~1; pSprite->cstat |= CSTAT_SPRITE_INVISIBLE; + if (pSprite->extra <= 0 || pSprite->extra >= kMaxXSprites) continue; + xsprite[pSprite->extra].waitTime = ClipLow(xsprite[pSprite->extra].waitTime, 1); + xsprite[pSprite->extra].state = 0; + break; + } + } + + for (int nSprite = headspritestat[kStatThing]; nSprite >= 0; nSprite = nextspritestat[nSprite]) { + if (sprite[nSprite].extra <= 0 || sprite[nSprite].extra >= kMaxXSprites) continue; + spritetype* pSprite = &sprite[nSprite]; XSPRITE *pXSprite = &xsprite[pSprite->extra]; + int nType = pSprite->type - kThingBase; - pSprite->clipdist = thingInfo[nType].at4; - pSprite->flags = thingInfo[nType].at5; - if (pSprite->flags&2) - pSprite->flags |= 4; + pXSprite->health = thingInfo[nType].health << 4; + pSprite->clipdist = thingInfo[nType].clipdist; + pSprite->flags = thingInfo[nType].flags; + if (pSprite->flags & kPhysGravity) pSprite->flags |= kPhysFalling; xvel[nSprite] = yvel[nSprite] = zvel[nSprite] = 0; - pXSprite->health = thingInfo[nType].at0<<4; + switch (pSprite->type) { case kThingArmedProxBomb: case kTrapMachinegun: @@ -2687,11 +2683,11 @@ void actInit(bool bSaveLoad) { pXSprite->state = 0; break; case kThingBloodChunks: { - SEQINST *pInst = GetInstance(3, nXSprite); + SEQINST *pInst = GetInstance(3, pSprite->extra); if (pInst && pInst->at13) { DICTNODE *hSeq = gSysRes.Lookup(pInst->at8, "SEQ"); if (!hSeq) break; - seqSpawn(pInst->at8, 3, nXSprite); + seqSpawn(pInst->at8, 3, pSprite->extra); } break; } @@ -2700,55 +2696,44 @@ void actInit(bool bSaveLoad) { break; } } - if (gGameOptions.nMonsterSettings == 0) - { + + if (gGameOptions.nMonsterSettings == 0) { gKillMgr.SetCount(0); - while (headspritestat[kStatDude] >= 0) - { + while (headspritestat[kStatDude] >= 0) { spritetype *pSprite = &sprite[headspritestat[kStatDude]]; - int nXSprite = pSprite->extra; - dassert(nXSprite > 0 && nXSprite < kMaxXSprites); - XSPRITE *pXSprite = &xsprite[nXSprite]; - // Drop Key - if (pXSprite->key > 0) - actDropObject(pSprite, 99 + pXSprite->key); + if (pSprite->extra > 0 && pSprite->extra < kMaxXSprites && xsprite[pSprite->extra].key > 0) // Drop Key + actDropObject(pSprite, kItemKeyBase + (xsprite[pSprite->extra].key - 1)); DeleteSprite(headspritestat[kStatDude]); } - } - else - { + } else { // by NoOne: WTF is this? /////////////// char unk[kDudeMax-kDudeBase]; memset(unk, 0, sizeof(unk)); - for (int nSprite = headspritestat[kStatDude]; nSprite >= 0; nSprite = nextspritestat[nSprite]) - { + for (int nSprite = headspritestat[kStatDude]; nSprite >= 0; nSprite = nextspritestat[nSprite]) { spritetype *pSprite = &sprite[nSprite]; if (pSprite->type < kDudeBase || pSprite->type >= kDudeMax) ThrowError("Non-enemy sprite (%d) in the enemy sprite list.\n", nSprite); - unk[pSprite->type-kDudeBase] = 1; + unk[pSprite->type - kDudeBase] = 1; } gKillMgr.sub_2641C(); /////////////// - for (int i = 0; i < kDudeMax-kDudeBase; i++) + for (int i = 0; i < kDudeMax - kDudeBase; i++) for (int j = 0; j < 7; j++) dudeInfo[i].at70[j] = mulscale8(DudeDifficulty[gGameOptions.nDifficulty], dudeInfo[i].startDamage[j]); for (int nSprite = headspritestat[kStatDude]; nSprite >= 0; nSprite = nextspritestat[nSprite]) { - spritetype *pSprite = &sprite[nSprite]; - int nXSprite = pSprite->extra; - dassert(nXSprite > 0 && nXSprite < kMaxXSprites); - XSPRITE *pXSprite = &xsprite[nXSprite]; - int nType = pSprite->type-kDudeBase; - int seqStartId = dudeInfo[nType].seqStartID; + if (sprite[nSprite].extra <= 0 || sprite[nSprite].extra >= kMaxXSprites) continue; + spritetype *pSprite = &sprite[nSprite]; XSPRITE *pXSprite = &xsprite[pSprite->extra]; + + int nType = pSprite->type - kDudeBase; int seqStartId = dudeInfo[nType].seqStartID; if (!IsPlayerSprite(pSprite)) { - switch (pSprite->type) { case kDudeModernCustom: case kDudeModernCustomBurning: - pSprite->cstat |= 4096 + 256 + 1; + pSprite->cstat |= 4096 + CSTAT_SPRITE_BLOCK_HITSCAN + CSTAT_SPRITE_BLOCK; seqStartId = getSeqStartId(pXSprite); // by NoOne: Custom Dude stores it's SEQ in data2 pXSprite->sysData1 = pXSprite->data3; // by NoOne move sndStartId to sysData1, because data3 used by the game; pXSprite->data3 = 0; @@ -2758,7 +2743,7 @@ void actInit(bool bSaveLoad) { fallthrough__; default: pSprite->clipdist = dudeInfo[nType].clipdist; - pSprite->cstat |= 4096 + 256 + 1; + pSprite->cstat |= 4096 + CSTAT_SPRITE_BLOCK_HITSCAN + CSTAT_SPRITE_BLOCK; break; } @@ -2767,10 +2752,9 @@ void actInit(bool bSaveLoad) { // By NoOne: add a way to set custom hp for every enemy - should work only if map just started and not loaded. if (!gModernMap || pXSprite->data4 <= 0) pXSprite->health = dudeInfo[nType].startHealth << 4; else pXSprite->health = ClipRange(pXSprite->data4 << 4, 1, 65535); - } - if (gSysRes.Lookup(seqStartId, "SEQ")) seqSpawn(seqStartId, 3, nXSprite); + if (gSysRes.Lookup(seqStartId, "SEQ")) seqSpawn(seqStartId, 3, pSprite->extra); } aiInit(); } @@ -2785,8 +2769,7 @@ void ConcussSprite(int a1, spritetype *pSprite, int x, int y, int z, int a6) int dist2 = 0x40000+dx*dx+dy*dy+dz*dz; dassert(dist2 > 0); a6 = scale(0x40000, a6, dist2); - if (pSprite->flags & 1) - { + if (pSprite->flags & kPhysMove) { int mass = 0; if (IsDudeSprite(pSprite)) { mass = dudeInfo[pSprite->type - kDudeBase].mass; @@ -2798,9 +2781,11 @@ void ConcussSprite(int a1, spritetype *pSprite, int x, int y, int z, int a6) } } else if (pSprite->type >= kThingBase && pSprite->type < kThingMax) - mass = thingInfo[pSprite->type - kThingBase].at2; + mass = thingInfo[pSprite->type - kThingBase].mass; else - ThrowError("Unexpected type in ConcussSprite(): Sprite: %d Type: %d Stat: %d", (int)pSprite->index, (int)pSprite->type, (int)pSprite->statnum); + return; + //else + //ThrowError("Unexpected type in ConcussSprite(): Sprite: %d Type: %d Stat: %d", (int)pSprite->index, (int)pSprite->type, (int)pSprite->statnum); int size = (tilesiz[pSprite->picnum].x*pSprite->xrepeat*tilesiz[pSprite->picnum].y*pSprite->yrepeat)>>1; dassert(mass > 0); @@ -2814,6 +2799,7 @@ void ConcussSprite(int a1, spritetype *pSprite, int x, int y, int z, int a6) yvel[nSprite] += dy; zvel[nSprite] += dz; } + actDamageSprite(a1, pSprite, DAMAGE_TYPE_3, a6); } @@ -3248,15 +3234,18 @@ void actKillDude(int nKillerSprite, spritetype *pSprite, DAMAGE_TYPE damageType, if (pXSprite->dropMsg > 0) actDropObject(pSprite, pXSprite->dropMsg); - int nRand = Random(100); switch (pSprite->type) { - case kDudeCultistTommy: + case kDudeCultistTommy: { + int nRand = Random(100); if (nRand < 10) actDropObject(pSprite, kItemWeaponTommygun); else if (nRand < 50) actDropObject(pSprite, kItemAmmoTommygunFew); + } break; - case kDudeCultistShotgun: + case kDudeCultistShotgun: { + int nRand = Random(100); if (nRand <= 10) actDropObject(pSprite, kItemWeaponSawedoff); else if (nRand <= 50) actDropObject(pSprite, kItemAmmoSawedoffFew); + } break; } @@ -3657,91 +3646,76 @@ void actKillDude(int nKillerSprite, spritetype *pSprite, DAMAGE_TYPE damageType, actPostSprite(pSprite->index, kStatThing); } -int actDamageSprite(int nSource, spritetype *pSprite, DAMAGE_TYPE damageType, int damage) -{ +int actDamageSprite(int nSource, spritetype *pSprite, DAMAGE_TYPE damageType, int damage) { dassert(nSource < kMaxSprites); - if (pSprite->flags&32) + if (pSprite->flags&32 || pSprite->extra <= 0 || pSprite->extra >= kMaxXSprites || xsprite[pSprite->extra].reference != pSprite->index) return 0; - int nXSprite = pSprite->extra; - if (nXSprite <= 0) - return 0; - dassert(nXSprite > 0 && nXSprite < kMaxXSprites); - XSPRITE *pXSprite = &xsprite[nXSprite]; - dassert(pXSprite->reference == pSprite->index); + + XSPRITE *pXSprite = &xsprite[pSprite->extra]; if ((pXSprite->health == 0 && pSprite->statnum != kStatDude) || pXSprite->locked) return 0; - if (nSource == -1) + + if (nSource == -1) nSource = pSprite->index; + PLAYER *pSourcePlayer = NULL; - if (IsPlayerSprite(&sprite[nSource])) - pSourcePlayer = &gPlayer[sprite[nSource].type-kDudePlayer1]; - if (!gGameOptions.bFriendlyFire && IsTargetTeammate(pSourcePlayer, pSprite)) - return 0; - switch (pSprite->statnum) - { - case kStatDude: - { - if (pSprite->type < kDudeBase || pSprite->type >= kDudeMax) - { - sprintf(buffer, "Bad Dude Failed: initial=%d type=%d %s\n", (int)pSprite->inittype, (int)pSprite->type, (int)(pSprite->flags&16) ? "RESPAWN" : "NORMAL"); - ThrowError(buffer); - } - dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); - int nType = pSprite->type-kDudeBase; - int nDamageFactor = dudeInfo[nType].at70[damageType]; - if (!nDamageFactor) - return 0; - if (nDamageFactor != 256) + if (IsPlayerSprite(&sprite[nSource])) pSourcePlayer = &gPlayer[sprite[nSource].type - kDudePlayer1]; + if (!gGameOptions.bFriendlyFire && IsTargetTeammate(pSourcePlayer, pSprite)) return 0; + + switch (pSprite->statnum) { + case kStatDude: { + if (!IsDudeSprite(pSprite)) + ThrowError("Bad Dude Failed: initial=%d type=%d %s\n", (int)pSprite->inittype, (int)pSprite->type, (int)(pSprite->flags & 16) ? "RESPAWN" : "NORMAL"); + int nType = pSprite->type - kDudeBase; int nDamageFactor = dudeInfo[nType].at70[damageType]; + + if (!nDamageFactor) return 0; + else if (nDamageFactor != 256) damage = mulscale8(damage, nDamageFactor); - if (!IsPlayerSprite(pSprite)) - { - if (!pXSprite->health) - return 0; + + if (!IsPlayerSprite(pSprite)) { + + if (pXSprite->health <= 0) return 0; damage = aiDamageSprite(pSprite, pXSprite, nSource, damageType, damage); - if (!pXSprite->health) - { - if (damageType == DAMAGE_TYPE_3 && damage < 160) - damageType = DAMAGE_TYPE_0; - actKillDude(nSource, pSprite, damageType, damage); - } - } - else - { - PLAYER *pPlayer = &gPlayer[pSprite->type-kDudePlayer1]; + if (pXSprite->health <= 0) + actKillDude(nSource, pSprite, ((damageType == DAMAGE_TYPE_3 && damage < 160) ? DAMAGE_TYPE_0 : damageType), damage); + + } else { + + PLAYER *pPlayer = &gPlayer[pSprite->type - kDudePlayer1]; if (pXSprite->health > 0 || playerSeqPlaying(pPlayer, 16)) damage = playerDamageSprite(nSource, pPlayer, damageType, damage); + + } } break; - } case kStatThing: dassert(pSprite->type >= kThingBase && pSprite->type < kThingMax); - int nType = pSprite->type-kThingBase; - int nDamageFactor = thingInfo[nType].at17[damageType]; - if (!nDamageFactor) - return 0; - if (nDamageFactor != 256) + int nType = pSprite->type - kThingBase; int nDamageFactor = thingInfo[nType].at17[damageType]; + + if (!nDamageFactor) return 0; + else if (nDamageFactor != 256) damage = mulscale8(damage, nDamageFactor); - pXSprite->health = ClipLow(pXSprite->health-damage, 0); - if (!pXSprite->health) - { - if (pSprite->type == kThingDroppedLifeLeech || pSprite->type == kModernThingEnemyLifeLeech) - { + + pXSprite->health = ClipLow(pXSprite->health - damage, 0); + if (pXSprite->health <= 0) { + switch (pSprite->type) { + case kThingDroppedLifeLeech: + case kModernThingEnemyLifeLeech: GibSprite(pSprite, GIBTYPE_14, NULL, NULL); - pXSprite->data1 = 0; - pXSprite->data2 = 0; - pXSprite->data3 = 0; - pXSprite->stateTimer = 0; - pXSprite->data4 = 0; - pXSprite->isTriggered = 0; - pXSprite->DudeLockout = 0; + pXSprite->data1 = pXSprite->data2 = pXSprite->data3 = pXSprite->DudeLockout = 0; + pXSprite->stateTimer = pXSprite->data4 = pXSprite->isTriggered = 0; if (pSprite->owner >= 0 && sprite[pSprite->owner].type == kDudeModernCustom) - sprite[pSprite->owner].owner = kMaxSprites -1; // By NoOne: indicates if custom dude had life leech. + sprite[pSprite->owner].owner = kMaxSprites - 1; // By NoOne: indicates if custom dude had life leech. + break; + default: + if (!(pSprite->flags & 16)) + actPropagateSpriteOwner(pSprite, &sprite[nSource]); + break; } - else if (!(pSprite->flags&16)) - actPropagateSpriteOwner(pSprite, &sprite[nSource]); trTriggerSprite(pSprite->index, pXSprite, kCmdOff); + switch (pSprite->type) { case kThingObjectGib: case kThingObjectExplode: @@ -3788,7 +3762,8 @@ int actDamageSprite(int nSource, spritetype *pSprite, DAMAGE_TYPE damageType, in } break; } - return damage>>4; + + return damage >> 4; } void actHitcodeToData(int a1, HITINFO *pHitInfo, int *a3, spritetype **a4, XSPRITE **a5, int *a6, walltype **a7, XWALL **a8, int *a9, sectortype **a10, XSECTOR **a11) @@ -3910,10 +3885,12 @@ void actImpactMissile(spritetype *pMissile, int hitCode) switch (hitCode) { case 0: case 4: - if (!pWallHit) break; + if (pWallHit) { spritetype* pFX = gFX.fxSpawn(FX_52, pMissile->sectnum, pMissile->x, pMissile->y, pMissile->z, 0); if (pFX) pFX->ang = (GetWallAngle(nWallHit) + 512) & 2047; - } + } + break; + } GibSprite(pMissile, GIBTYPE_24, NULL, NULL); actPostSprite(pMissile->index, kStatFree); break; @@ -4202,9 +4179,9 @@ void ProcessTouchObjects(spritetype *pSprite, int nXSprite) { int nType = pSprite2->type-kThingBase; THINGINFO *pThingInfo = &thingInfo[nType]; - if (pThingInfo->at5&1) + if (pThingInfo->flags&1) pSprite2->flags |= 1; - if (pThingInfo->at5&2) + if (pThingInfo->flags&2) pSprite2->flags |= 4; // Inlined ? xvel[pSprite2->index] += mulscale(4, pSprite2->x-sprite[nSprite].x, 2); @@ -5454,7 +5431,7 @@ void actExplodeSprite(spritetype *pSprite) { XSPRITE *pXSprite = &xsprite[nXSprite]; pXSprite->state = 1; - pXSprite->health = thingInfo[0].at0<<4; + pXSprite->health = thingInfo[0].health<<4; } else actPostSprite(pSprite->index, kStatFree); @@ -5793,9 +5770,9 @@ void actProcessSprites(void) { int nType = pSprite->type - kThingBase; THINGINFO *pThingInfo = &thingInfo[nType]; - if (pThingInfo->at5 & 1) + if (pThingInfo->flags & 1) pSprite->flags |= 1; - if (pThingInfo->at5 & 2) + if (pThingInfo->flags & 2) pSprite->flags |= 4; } if (pSprite->flags&3) @@ -6492,9 +6469,9 @@ spritetype * actSpawnThing(int nSector, int x, int y, int z, int nThingType) dassert(nXThing > 0 && nXThing < kMaxXSprites); XSPRITE *pXThing = &xsprite[nXThing]; THINGINFO *pThingInfo = &thingInfo[nType]; - pXThing->health = pThingInfo->at0<<4; - pSprite->clipdist = pThingInfo->at4; - pSprite->flags = pThingInfo->at5; + pXThing->health = pThingInfo->health<<4; + pSprite->clipdist = pThingInfo->clipdist; + pSprite->flags = pThingInfo->flags; if (pSprite->flags & 2) pSprite->flags |= 4; pSprite->cstat |= pThingInfo->atf; @@ -6942,7 +6919,7 @@ void actFireVector(spritetype *pShooter, int a2, int a3, int a4, int a5, int a6, } if (pSprite->statnum == kStatThing) { - int t = thingInfo[pSprite->type-kThingBase].at2; + int t = thingInfo[pSprite->type-kThingBase].mass; if (t > 0 && pVectorData->at5) { int t2 = divscale(pVectorData->at5, t, 8); @@ -7129,7 +7106,7 @@ void TreeToGibCallback(int, int nXSprite) pXSprite->data1 = 15; pXSprite->data2 = 0; pXSprite->data3 = 0; - pXSprite->health = thingInfo[17].at0; + pXSprite->health = thingInfo[17].health; pXSprite->data4 = 312; pSprite->cstat |= 257; } @@ -7143,7 +7120,7 @@ void DudeToGibCallback1(int, int nXSprite) pXSprite->data1 = 8; pXSprite->data2 = 0; pXSprite->data3 = 0; - pXSprite->health = thingInfo[26].at0; + pXSprite->health = thingInfo[26].health; pXSprite->data4 = 319; pXSprite->triggerOnce = 0; pXSprite->isTriggered = 0; @@ -7161,7 +7138,7 @@ void DudeToGibCallback2(int, int nXSprite) pXSprite->data1 = 3; pXSprite->data2 = 0; pXSprite->data3 = 0; - pXSprite->health = thingInfo[26].at0; + pXSprite->health = thingInfo[26].health; pXSprite->data4 = 319; pXSprite->triggerOnce = 0; pXSprite->isTriggered = 0; diff --git a/source/blood/src/actor.h b/source/blood/src/actor.h index 2a11dfbb3..e40577e4b 100644 --- a/source/blood/src/actor.h +++ b/source/blood/src/actor.h @@ -69,10 +69,10 @@ enum VECTOR_TYPE { struct THINGINFO { - short at0; // health - short at2; // mass - unsigned char at4; // clipdist - short at5; // flags + short health; // health + short mass; // mass + unsigned char clipdist; // clipdist + short flags; // flags int at7; // elasticity int atb; // damage resistance short atf; // cstat @@ -191,7 +191,6 @@ extern int gDudeDrag; extern short gAffectedSectors[kMaxSectors]; extern short gAffectedXWalls[kMaxXWalls]; - inline bool IsPlayerSprite(spritetype *pSprite) { if (pSprite->type >= kDudePlayer1 && pSprite->type <= kDudePlayer8) diff --git a/source/blood/src/aispid.cpp b/source/blood/src/aispid.cpp index 7e2800ace..3918bef63 100644 --- a/source/blood/src/aispid.cpp +++ b/source/blood/src/aispid.cpp @@ -121,10 +121,15 @@ static void SpidBiteSeqCallback(int, int nXSprite) actFireVector(pSprite, 0, 0, dx, dy, dz, VECTOR_TYPE_17); sub_70D30(pXTarget, 8, 16); break; - case kDudeSpiderMother: + case kDudeSpiderMother: { + actFireVector(pSprite, 0, 0, dx, dy, dz, VECTOR_TYPE_17); + + dx += Random2(2000); + dy += Random2(2000); + dz += Random2(2000); actFireVector(pSprite, 0, 0, dx, dy, dz, VECTOR_TYPE_17); - actFireVector(pSprite, 0, 0, dx + Random2(2000), dy + Random2(2000), dz + Random2(2000), VECTOR_TYPE_17); sub_70D30(pXTarget, 8, 16); + } break; } } diff --git a/source/blood/src/asound.cpp b/source/blood/src/asound.cpp index 33160bb68..3c258f845 100644 --- a/source/blood/src/asound.cpp +++ b/source/blood/src/asound.cpp @@ -27,6 +27,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "fx_man.h" #include "common_game.h" //#include "blood.h" +#include "view.h" #include "config.h" #include "db.h" #include "player.h" @@ -116,49 +117,52 @@ void ambInit(void) { ambKillAll(); memset(ambChannels, 0, sizeof(ambChannels)); - for (int nSprite = headspritestat[kStatAmbience]; nSprite >= 0; nSprite = nextspritestat[nSprite]) - { - spritetype *pSprite = &sprite[nSprite]; - int nXSprite = pSprite->extra; - if (nXSprite > 0 && nXSprite < kMaxXSprites) - { - XSPRITE *pXSprite = &xsprite[nXSprite]; - if (pXSprite->data1 < pXSprite->data2) - { - int i; - AMB_CHANNEL *pChannel = ambChannels; - for (i = 0; i < nAmbChannels; i++, pChannel++) - if (pXSprite->data3 == pChannel->at8) - break; - if (i == nAmbChannels) - { - if (i >= kMaxAmbChannel) - { - pSprite->owner = -1; - continue; - } - int nSFX = pXSprite->data3; - DICTNODE *pSFXNode = gSoundRes.Lookup(nSFX, "SFX"); - if (!pSFXNode) - ThrowError("Missing sound #%d used in ambient sound generator %d\n", nSFX); - SFX *pSFX = (SFX*)gSoundRes.Load(pSFXNode); - DICTNODE *pRAWNode = gSoundRes.Lookup(pSFX->rawName, "RAW"); - if (!pRAWNode) - ThrowError("Missing RAW sound \"%s\" used in ambient sound generator %d\n", pSFX->rawName, nSFX); - if (pRAWNode->size > 0) - { - pChannel->at14 = pRAWNode->size; - pChannel->at8 = nSFX; - pChannel->atc = pRAWNode; - pChannel->at14 = pRAWNode->size; - pChannel->at10 = (char*)gSoundRes.Lock(pRAWNode); - pChannel->at18 = pSFX->format; - nAmbChannels++; - } - } - pSprite->owner = i; + for (int nSprite = headspritestat[kStatAmbience]; nSprite >= 0; nSprite = nextspritestat[nSprite]) { + if (sprite[nSprite].extra <= 0 || sprite[nSprite].extra >= kMaxXSprites) continue; + + XSPRITE *pXSprite = &xsprite[sprite[nSprite].extra]; + if (pXSprite->data1 >= pXSprite->data2) continue; + + int i; AMB_CHANNEL *pChannel = ambChannels; + for (i = 0; i < nAmbChannels; i++, pChannel++) + if (pXSprite->data3 == pChannel->at8) break; + + if (i == nAmbChannels) { + + if (i >= kMaxAmbChannel) { + sprite[nSprite].owner = -1; + continue; } + + int nSFX = pXSprite->data3; + DICTNODE *pSFXNode = gSoundRes.Lookup(nSFX, "SFX"); + if (!pSFXNode) { + //ThrowError("Missing sound #%d used in ambient sound generator %d\n", nSFX); + viewSetSystemMessage("Missing sound #%d used in ambient sound generator #%d\n", nSFX); + continue; + } + + SFX *pSFX = (SFX*)gSoundRes.Load(pSFXNode); + DICTNODE *pRAWNode = gSoundRes.Lookup(pSFX->rawName, "RAW"); + if (!pRAWNode) { + //ThrowError("Missing RAW sound \"%s\" used in ambient sound generator %d\n", pSFX->rawName, nSFX); + viewSetSystemMessage("Missing RAW sound \"%s\" used in ambient sound generator %d\n", pSFX->rawName, nSFX); + continue; + } + + if (pRAWNode->size > 0) { + pChannel->at14 = pRAWNode->size; + pChannel->at8 = nSFX; + pChannel->atc = pRAWNode; + pChannel->at14 = pRAWNode->size; + pChannel->at10 = (char*)gSoundRes.Lock(pRAWNode); + pChannel->at18 = pSFX->format; + nAmbChannels++; + } + } + + sprite[nSprite].owner = i; } } diff --git a/source/blood/src/blood.cpp b/source/blood/src/blood.cpp index 7a2bb6d5c..826286614 100644 --- a/source/blood/src/blood.cpp +++ b/source/blood/src/blood.cpp @@ -629,6 +629,10 @@ void StartLevel(GAMEOPTIONS *gameOptions) case kModernDudeTargetChanger: changespritestat(i, kStatModernDudeTargetChanger); break; + // add statnum for faster searching of already enabled qav players + case kModernPlayQAV: + changespritestat(i, kStatModernPlayQAV); + break; // remove kStatItem status from random item generators case kModernRandom: case kModernRandom2: diff --git a/source/blood/src/callback.cpp b/source/blood/src/callback.cpp index 2fae2e4f4..82ca9865f 100644 --- a/source/blood/src/callback.cpp +++ b/source/blood/src/callback.cpp @@ -227,67 +227,66 @@ void fxDynPuff(int nSprite) // 8 void Respawn(int nSprite) // 9 { spritetype *pSprite = &sprite[nSprite]; - int nXSprite = pSprite->extra; - dassert(nXSprite > 0 && nXSprite < kMaxXSprites); - XSPRITE *pXSprite = &xsprite[nXSprite]; - if (pSprite->statnum != kStatRespawn && pSprite->statnum != kStatThing) - ThrowError("Sprite %d is not on Respawn or Thing list\n", nSprite); - if (!(pSprite->flags&16)) - ThrowError("Sprite %d does not have the respawn attribute\n", nSprite); - switch (pXSprite->respawnPending) - { - case 1: - { - int nTime = mulscale16(actGetRespawnTime(pSprite), 0x4000); - pXSprite->respawnPending = 2; - evPost(nSprite, 3, nTime, kCallbackRespawn); - break; + dassert(pSprite->extra > 0 && pSprite->extra < kMaxXSprites); + XSPRITE *pXSprite = &xsprite[pSprite->extra]; + + if (pSprite->statnum != kStatRespawn && pSprite->statnum != kStatThing) { + viewSetSystemMessage("Sprite #%d is not on Respawn or Thing list\n", nSprite); + return; + } else if (!(pSprite->flags & kHitagRespawn)) { + viewSetSystemMessage("Sprite #%d does not have the respawn attribute\n", nSprite); + return; } - case 2: - { - int nTime = mulscale16(actGetRespawnTime(pSprite), 0x2000); - pXSprite->respawnPending = 3; - evPost(nSprite, 3, nTime, kCallbackRespawn); - break; - } - case 3: - { - dassert(pSprite->owner != kStatRespawn); - dassert(pSprite->owner >= 0 && pSprite->owner < kMaxStatus); - ChangeSpriteStat(nSprite, pSprite->owner); - pSprite->type = pSprite->inittype; - pSprite->owner = -1; - pSprite->flags &= ~16; - xvel[nSprite] = yvel[nSprite] = zvel[nSprite] = 0; - pXSprite->respawnPending = 0; - pXSprite->burnTime = 0; - pXSprite->isTriggered = 0; - if (pSprite->type >= kDudeBase && pSprite->type < kDudeMax) - { - int nType = pSprite->type-kDudeBase; - pSprite->x = baseSprite[nSprite].x; - pSprite->y = baseSprite[nSprite].y; - pSprite->z = baseSprite[nSprite].z; - pSprite->cstat |= 0x1101; - pSprite->clipdist = dudeInfo[nType].clipdist; - pXSprite->health = dudeInfo[nType].startHealth<<4; - if (gSysRes.Lookup(dudeInfo[nType].seqStartID, "SEQ")) - seqSpawn(dudeInfo[nType].seqStartID, 3, pSprite->extra, -1); - aiInitSprite(pSprite); - pXSprite->key = 0; + + switch (pXSprite->respawnPending) { + case 1: { + int nTime = mulscale16(actGetRespawnTime(pSprite), 0x4000); + pXSprite->respawnPending = 2; + evPost(nSprite, 3, nTime, kCallbackRespawn); + break; } - if (pSprite->type == kThingTNTBarrel) - { - pSprite->cstat |= CSTAT_SPRITE_BLOCK | CSTAT_SPRITE_BLOCK_HITSCAN; - pSprite->cstat &= (unsigned short)~CSTAT_SPRITE_INVISIBLE; + case 2: { + int nTime = mulscale16(actGetRespawnTime(pSprite), 0x2000); + pXSprite->respawnPending = 3; + evPost(nSprite, 3, nTime, kCallbackRespawn); + break; + } + case 3: { + dassert(pSprite->owner != kStatRespawn); + dassert(pSprite->owner >= 0 && pSprite->owner < kMaxStatus); + ChangeSpriteStat(nSprite, pSprite->owner); + pSprite->type = pSprite->inittype; + pSprite->owner = -1; + pSprite->flags &= ~16; + xvel[nSprite] = yvel[nSprite] = zvel[nSprite] = 0; + pXSprite->respawnPending = 0; + pXSprite->burnTime = 0; + pXSprite->isTriggered = 0; + if (IsDudeSprite(pSprite)) { + + int nType = pSprite->type-kDudeBase; + pSprite->x = baseSprite[nSprite].x; + pSprite->y = baseSprite[nSprite].y; + pSprite->z = baseSprite[nSprite].z; + pSprite->cstat |= 0x1101; + pSprite->clipdist = dudeInfo[nType].clipdist; + pXSprite->health = dudeInfo[nType].startHealth<<4; + if (gSysRes.Lookup(dudeInfo[nType].seqStartID, "SEQ")) + seqSpawn(dudeInfo[nType].seqStartID, 3, pSprite->extra, -1); + aiInitSprite(pSprite); + pXSprite->key = 0; + + } else if (pSprite->type == kThingTNTBarrel) { + + pSprite->cstat |= CSTAT_SPRITE_BLOCK | CSTAT_SPRITE_BLOCK_HITSCAN; + pSprite->cstat &= (unsigned short)~CSTAT_SPRITE_INVISIBLE; + + } + + gFX.fxSpawn(FX_29, pSprite->sectnum, pSprite->x, pSprite->y, pSprite->z, 0); + sfxPlay3DSound(pSprite, 350, -1, 0); + break; } - gFX.fxSpawn(FX_29, pSprite->sectnum, pSprite->x, pSprite->y, pSprite->z, 0); - sfxPlay3DSound(pSprite, 350, -1, 0); - break; - } - default: - ThrowError("Unexpected respawnPending value = %d", pXSprite->respawnPending); - break; } } diff --git a/source/blood/src/callback.h b/source/blood/src/callback.h index 71bb52bb3..d007190a6 100644 --- a/source/blood/src/callback.h +++ b/source/blood/src/callback.h @@ -51,7 +51,7 @@ enum CALLBACK_ID { kCallbackDropVoodoo = 21, // unused kCallbackMissileBurst = 22, // by NoOne kCallbackMissileSpriteBlock = 23, // by NoOne - kCallbackMax = 24 + kCallbackMax = 24, }; extern void (*gCallback[kCallbackMax])(int); diff --git a/source/blood/src/common_game.h b/source/blood/src/common_game.h index 389509d26..3da20a66b 100644 --- a/source/blood/src/common_game.h +++ b/source/blood/src/common_game.h @@ -99,7 +99,8 @@ void QuitGame(void); #define kStatFlare 14 #define kStatDebris 15 #define kStatPathMarker 16 -#define kStatModernDudeTargetChanger 20 +#define kStatModernDudeTargetChanger 20 // gModernMap only +#define kStatModernPlayQAV 21 // gModernMap only #define kStatFree 1024 #define kLensSize 80 @@ -159,7 +160,8 @@ enum { kModernObjDataAccumulator = 37, kModernEffectSpawner = 38, kModernWindGenerator = 39, - kModernConcussSprite = 712, + kModernConcussSprite = 712, /// WIP + kModernPlayQAV = 713, /// WIP // decorations kDecorationTorch = 30, diff --git a/source/blood/src/endgame.cpp b/source/blood/src/endgame.cpp index a969ce1ed..f9d624f4a 100644 --- a/source/blood/src/endgame.cpp +++ b/source/blood/src/endgame.cpp @@ -158,19 +158,18 @@ void CKillMgr::sub_2641C(void) for (int nSprite = headspritestat[kStatDude]; nSprite >= 0; nSprite = nextspritestat[nSprite]) { spritetype *pSprite = &sprite[nSprite]; - if (pSprite->type < kDudeBase || pSprite->type >= kDudeMax) - ThrowError("Non-enemy sprite (%d) in the enemy sprite list.", nSprite); - - if (pSprite->statnum == kStatDude) { - switch (pSprite->type) { - case kDudeBat: - case kDudeRat: - case kDudeBurningInnocent: - case kDudeInnocent: - return; - } + if (IsDudeSprite(pSprite)) { + if (pSprite->statnum == kStatDude) { + switch (pSprite->type) { + case kDudeBat: + case kDudeRat: + case kDudeBurningInnocent: + case kDudeInnocent: + return; + } - at0++; + at0++; + } } } @@ -229,22 +228,20 @@ void CSecretMgr::SetCount(int nCount) void CSecretMgr::Found(int nType) { - if (nType < 0) - ThrowError("Invalid secret type %d triggered.", nType); - if (nType == 0) - at4++; - else - at8++; - if (gGameOptions.nGameType == 0) - { - switch (Random(2)) - { - case 0: - viewSetMessage("A secret is revealed.", 0, MESSAGE_PRIORITY_SECRET); - break; - case 1: - viewSetMessage("You found a secret.", 0, MESSAGE_PRIORITY_SECRET); - break; + if (nType == 0) at4++; + else if (nType < 0) { + viewSetSystemMessage("Invalid secret type %d triggered.", nType); + return; + } else at8++; + + if (gGameOptions.nGameType == 0) { + switch (Random(2)) { + case 0: + viewSetMessage("A secret is revealed.", 0, MESSAGE_PRIORITY_SECRET); + break; + case 1: + viewSetMessage("You found a secret.", 0, MESSAGE_PRIORITY_SECRET); + break; } } } diff --git a/source/blood/src/eventq.cpp b/source/blood/src/eventq.cpp index 849a2643b..ccb7e0ed6 100644 --- a/source/blood/src/eventq.cpp +++ b/source/blood/src/eventq.cpp @@ -82,32 +82,25 @@ RXBUCKET rxBucket[kMaxChannels+1]; int GetBucketChannel(const RXBUCKET *pRX) { - switch (pRX->type) - { - case 6: - { - int nIndex = pRX->index; - int nXIndex = sector[nIndex].extra; - dassert(nXIndex > 0); - return xsector[nXIndex].rxID; - } - case 0: - { - int nIndex = pRX->index; - int nXIndex = wall[nIndex].extra; - dassert(nXIndex > 0); - return xwall[nXIndex].rxID; - } - case 3: - { - int nIndex = pRX->index; - int nXIndex = sprite[nIndex].extra; - dassert(nXIndex > 0); - return xsprite[nXIndex].rxID; - } - default: - ThrowError("Unexpected rxBucket type %d, index %d", pRX->type, pRX->index); - break; + switch (pRX->type) { + case 6: { + int nIndex = pRX->index; + int nXIndex = sector[nIndex].extra; + dassert(nXIndex > 0); + return xsector[nXIndex].rxID; + } + case 0: { + int nIndex = pRX->index; + int nXIndex = wall[nIndex].extra; + dassert(nXIndex > 0); + return xwall[nXIndex].rxID; + } + case 3: { + int nIndex = pRX->index; + int nXIndex = sprite[nIndex].extra; + dassert(nXIndex > 0); + return xsprite[nXIndex].rxID; + } } return 0; } diff --git a/source/blood/src/seq.cpp b/source/blood/src/seq.cpp index 82caf18c4..f180782a7 100644 --- a/source/blood/src/seq.cpp +++ b/source/blood/src/seq.cpp @@ -38,6 +38,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "gameutil.h" #include "actor.h" #include "tile.h" +#include "view.h" BEGIN_BLD_NS @@ -378,11 +379,14 @@ void UnlockInstance(SEQINST *pInst) void seqSpawn(int a1, int a2, int a3, int a4) { SEQINST *pInst = GetInstance(a2, a3); - if (!pInst) - return; + if (!pInst) return; + DICTNODE *hSeq = gSysRes.Lookup(a1, "SEQ"); - if (!hSeq) - ThrowError("Missing sequence #%d", a1); + if (!hSeq) { + viewSetSystemMessage("Missing sequence #%d", a1); + return; + } + int i = activeCount; if (pInst->at13) { @@ -577,8 +581,10 @@ void SeqLoadSave::Load(void) { int nSeq = pInst->at8; DICTNODE *hSeq = gSysRes.Lookup(nSeq, "SEQ"); - if (!hSeq) - ThrowError("Missing sequence #%d", nSeq); + if (!hSeq) { + viewSetSystemMessage("Missing sequence #%d", nSeq); + continue; + } Seq *pSeq = (Seq*)gSysRes.Lock(hSeq); if (memcmp(pSeq->signature, "SEQ\x1a", 4) != 0) ThrowError("Invalid sequence %d", nSeq); diff --git a/source/blood/src/sfx.cpp b/source/blood/src/sfx.cpp index a93a37ed6..9bc27ec1a 100644 --- a/source/blood/src/sfx.cpp +++ b/source/blood/src/sfx.cpp @@ -119,18 +119,15 @@ void Calc3DValues(BONKLE *pBonkle) void sfxPlay3DSound(int x, int y, int z, int soundId, int nSector) { - if (!SoundToggle) - return; - if (soundId < 0) - ThrowError("Invalid sound ID"); + if (!SoundToggle || soundId < 0) return; + DICTNODE *hRes = gSoundRes.Lookup(soundId, "SFX"); - if (!hRes) - return; + if (!hRes)return; SFX *pEffect = (SFX*)gSoundRes.Load(hRes); hRes = gSoundRes.Lookup(pEffect->rawName, "RAW"); - if (!hRes) - return; + if (!hRes) return; + int v1c, v18; v1c = v18 = mulscale16(pEffect->pitch, sndGetRate(pEffect->format)); if (nBonkles >= 256) diff --git a/source/blood/src/tile.cpp b/source/blood/src/tile.cpp index d5b69c0d1..c3605f086 100644 --- a/source/blood/src/tile.cpp +++ b/source/blood/src/tile.cpp @@ -35,16 +35,19 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "globals.h" #include "resource.h" #include "tile.h" +#include "view.h" BEGIN_BLD_NS void qloadvoxel(int32_t nVoxel) { static int nLastVoxel = 0; - dassert(nVoxel >= 0 && nVoxel < kMaxVoxels); DICTNODE *hVox = gSysRes.Lookup(nVoxel, "KVX"); - if (!hVox) - ThrowError("Missing voxel #%d", nVoxel); + if (!hVox) { + viewSetSystemMessage("Missing voxel #%d (max voxels: %d)", nVoxel, kMaxVoxels); + return; + } + if (!hVox->lockCount) voxoff[nLastVoxel][0] = 0; nLastVoxel = nVoxel; diff --git a/source/blood/src/triggers.cpp b/source/blood/src/triggers.cpp index 769cdc6c3..e972ab84f 100644 --- a/source/blood/src/triggers.cpp +++ b/source/blood/src/triggers.cpp @@ -52,6 +52,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "view.h" #include "sectorfx.h" #include "messages.h" +#include "weapon.h" BEGIN_BLD_NS @@ -406,10 +407,10 @@ void OperateSprite(int nSprite, XSPRITE *pXSprite, EVENT event) case kMarkerLowStack: case kMarkerPath: switch (pXSprite->command) { - case kCmdLink: - if (pXSprite->txID <= 0) return; - evSend(nSprite, 3, pXSprite->txID, (COMMAND_ID)pXSprite->command); - return; + case kCmdLink: + if (pXSprite->txID <= 0) return; + evSend(nSprite, 3, pXSprite->txID, (COMMAND_ID)pXSprite->command); + return; } break; // go normal operate switch @@ -816,6 +817,36 @@ void OperateSprite(int nSprite, XSPRITE *pXSprite, EVENT event) break; } return; + case kModernPlayQAV: // WIP + PLAYER* pPlayer = &gPlayer[pXSprite->data1]; + switch (event.cmd) { + case kCmdOff: + pPlayer->atbd = pXSprite->sysData1; + if (pXSprite->state == 1) SetSpriteState(nSprite, pXSprite, 0); + if (pPlayer->atbd != 0) + WeaponRaise(pPlayer); + break; + case kCmdOn: + evKill(nSprite, 3); // queue overflow protect + disableQAVPlayers(pSprite); + if (pXSprite->state == 0) SetSpriteState(nSprite, pXSprite, 1); + if (pPlayer->atbd != 0) { + pXSprite->sysData1 = pPlayer->atbd; // save current weapon + WeaponLower(pPlayer); + } + fallthrough__; + case kCmdRepeat: + if (pPlayer->at26 != pXSprite->data2) + StartQAV(&gPlayer[pXSprite->data1], pXSprite->data2); + + if (pXSprite->busyTime > 0) evPost(nSprite, 3, pXSprite->busyTime, kCmdRepeat); + break; + default: + if (pXSprite->state == 0) evPost(nSprite, 3, 0, kCmdOn); + else evPost(nSprite, 3, 0, kCmdOff); + break; + } + return; } } @@ -1711,6 +1742,7 @@ void SetupGibWallState(walltype *pWall, XWALL *pXWall) void OperateWall(int nWall, XWALL *pXWall, EVENT event) { walltype *pWall = &wall[nWall]; + switch (event.cmd) { case kCmdLock: pXWall->locked = 1; @@ -1723,28 +1755,30 @@ void OperateWall(int nWall, XWALL *pXWall, EVENT event) { return; } + // by NoOne: make 1-Way switch type for walls to work... if (gModernMap) { - // by NoOne: make 1-Way switch type for walls to work... switch (pWall->type) { - case kSwitchOneWay: - switch (event.cmd) { - case kCmdOff: - SetWallState(nWall, pXWall, 0); - break; - case kCmdOn: - SetWallState(nWall, pXWall, 1); - break; - default: - SetWallState(nWall, pXWall, pXWall->restState ^ 1); - break; - } - return; + case kSwitchOneWay: + switch (event.cmd) { + case kCmdOff: + SetWallState(nWall, pXWall, 0); + break; + case kCmdOn: + SetWallState(nWall, pXWall, 1); + break; + default: + SetWallState(nWall, pXWall, pXWall->restState ^ 1); + break; + } + return; + default: + break; } - } else { + } - switch (pWall->type) { + switch (pWall->type) { case kWallGib: if (GetWallType(nWall) != pWall->type) break; char bStatus; @@ -1771,22 +1805,22 @@ void OperateWall(int nWall, XWALL *pXWall, EVENT event) { } } return; - } - - } - - switch (event.cmd) { - case kCmdOff: - SetWallState(nWall, pXWall, 0); - break; - case kCmdOn: - SetWallState(nWall, pXWall, 1); - break; default: - SetWallState(nWall, pXWall, pXWall->state ^ 1); - break; + switch (event.cmd) { + case kCmdOff: + SetWallState(nWall, pXWall, 0); + break; + case kCmdOn: + SetWallState(nWall, pXWall, 1); + break; + default: + SetWallState(nWall, pXWall, pXWall->state ^ 1); + break; + } + return; } + } void SectorStartSound(int nSector, int nState) @@ -3758,6 +3792,14 @@ bool dudeCanSeeTarget(XSPRITE* pXDude, DUDEINFO* pDudeInfo, spritetype* pTarget) } +void disableQAVPlayers(spritetype* pException) { + for (int nSprite = headspritestat[kStatModernPlayQAV]; nSprite >= 0; nSprite = nextspritestat[nSprite]) { + if (nSprite == pException->index || sprite[nSprite].extra < 0) continue; + else if (xsprite[sprite[nSprite].extra].state == 1) + evPost(nSprite, 3, 0, kCmdOff); + } +} + // by NoOne: this function required if monsters in genIdle ai state. It wakes up monsters // when kModernDudeTargetChanger goes to off state, so they won't ignore the world. void activateDudes(int rx) { diff --git a/source/blood/src/triggers.h b/source/blood/src/triggers.h index 1fea456b7..8596da82b 100644 --- a/source/blood/src/triggers.h +++ b/source/blood/src/triggers.h @@ -77,6 +77,7 @@ void useTeleportTarget(XSPRITE* pXSource, spritetype* pSprite); void usePropertiesChanger(XSPRITE* pXSource, short objType, int objIndex); void TeleFrag(int nKiller, int nSector); bool valueIsBetween(int val, int min, int max); +void disableQAVPlayers(spritetype* pException); // ------------------------------------------------------- diff --git a/source/blood/src/weapon.h b/source/blood/src/weapon.h index 99057ada3..9060da386 100644 --- a/source/blood/src/weapon.h +++ b/source/blood/src/weapon.h @@ -35,5 +35,5 @@ void WeaponLower(PLAYER *pPlayer); char WeaponUpgrade(PLAYER *pPlayer, char newWeapon); void WeaponProcess(PLAYER *pPlayer); void sub_51340(spritetype *pMissile, int a2); - +void StartQAV(PLAYER* pPlayer, int nWeaponQAV, int a3 = -1, char a4 = 0); END_BLD_NS