- 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
This commit is contained in:
Grind Core 2019-10-12 23:45:46 +03:00 committed by Christoph Oelckers
parent 08dfee073c
commit 16d4aebbb4
16 changed files with 389 additions and 360 deletions

View file

@ -2645,41 +2645,37 @@ void actInit(bool bSaveLoad) {
} }
} }
for (int nSprite = headspritestat[kStatItem]; nSprite >= 0; nSprite = nextspritestat[nSprite]) for (int nSprite = headspritestat[kStatItem]; nSprite >= 0; nSprite = nextspritestat[nSprite]) {
{ switch (sprite[nSprite].type) {
spritetype *pSprite = &sprite[nSprite]; case kItemWeaponVoodooDoll:
if (pSprite->type == kItemWeaponVoodooDoll) sprite[nSprite].type = kAmmoItemVoodooDoll;
pSprite->type = kAmmoItemVoodooDoll; break;
}
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[kStatThing]; nSprite >= 0; nSprite = nextspritestat[nSprite])
{ for (int nSprite = headspritestat[kStatTraps]; nSprite >= 0; nSprite = nextspritestat[nSprite]) {
spritetype *pSprite = &sprite[nSprite]; spritetype *pSprite = &sprite[nSprite];
int nXSprite = pSprite->extra; switch (pSprite->type) {
if (nXSprite <= 0 || nXSprite >= kMaxXSprites) case kTrapExploder:
ThrowError("WARNING: Sprite %d is on the wrong status list!\n", nSprite); pSprite->cstat &= ~1; pSprite->cstat |= CSTAT_SPRITE_INVISIBLE;
XSPRITE *pXSprite = &xsprite[nXSprite]; 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; int nType = pSprite->type - kThingBase;
pSprite->clipdist = thingInfo[nType].at4; pXSprite->health = thingInfo[nType].health << 4;
pSprite->flags = thingInfo[nType].at5; pSprite->clipdist = thingInfo[nType].clipdist;
if (pSprite->flags&2) pSprite->flags = thingInfo[nType].flags;
pSprite->flags |= 4; if (pSprite->flags & kPhysGravity) pSprite->flags |= kPhysFalling;
xvel[nSprite] = yvel[nSprite] = zvel[nSprite] = 0; xvel[nSprite] = yvel[nSprite] = zvel[nSprite] = 0;
pXSprite->health = thingInfo[nType].at0<<4;
switch (pSprite->type) { switch (pSprite->type) {
case kThingArmedProxBomb: case kThingArmedProxBomb:
case kTrapMachinegun: case kTrapMachinegun:
@ -2687,11 +2683,11 @@ void actInit(bool bSaveLoad) {
pXSprite->state = 0; pXSprite->state = 0;
break; break;
case kThingBloodChunks: { case kThingBloodChunks: {
SEQINST *pInst = GetInstance(3, nXSprite); SEQINST *pInst = GetInstance(3, pSprite->extra);
if (pInst && pInst->at13) { if (pInst && pInst->at13) {
DICTNODE *hSeq = gSysRes.Lookup(pInst->at8, "SEQ"); DICTNODE *hSeq = gSysRes.Lookup(pInst->at8, "SEQ");
if (!hSeq) break; if (!hSeq) break;
seqSpawn(pInst->at8, 3, nXSprite); seqSpawn(pInst->at8, 3, pSprite->extra);
} }
break; break;
} }
@ -2700,55 +2696,44 @@ void actInit(bool bSaveLoad) {
break; break;
} }
} }
if (gGameOptions.nMonsterSettings == 0)
{ if (gGameOptions.nMonsterSettings == 0) {
gKillMgr.SetCount(0); gKillMgr.SetCount(0);
while (headspritestat[kStatDude] >= 0) while (headspritestat[kStatDude] >= 0) {
{
spritetype *pSprite = &sprite[headspritestat[kStatDude]]; spritetype *pSprite = &sprite[headspritestat[kStatDude]];
int nXSprite = pSprite->extra; if (pSprite->extra > 0 && pSprite->extra < kMaxXSprites && xsprite[pSprite->extra].key > 0) // Drop Key
dassert(nXSprite > 0 && nXSprite < kMaxXSprites); actDropObject(pSprite, kItemKeyBase + (xsprite[pSprite->extra].key - 1));
XSPRITE *pXSprite = &xsprite[nXSprite];
// Drop Key
if (pXSprite->key > 0)
actDropObject(pSprite, 99 + pXSprite->key);
DeleteSprite(headspritestat[kStatDude]); DeleteSprite(headspritestat[kStatDude]);
} }
} } else {
else
{
// by NoOne: WTF is this? // by NoOne: WTF is this?
/////////////// ///////////////
char unk[kDudeMax-kDudeBase]; char unk[kDudeMax-kDudeBase];
memset(unk, 0, sizeof(unk)); 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]; spritetype *pSprite = &sprite[nSprite];
if (pSprite->type < kDudeBase || pSprite->type >= kDudeMax) if (pSprite->type < kDudeBase || pSprite->type >= kDudeMax)
ThrowError("Non-enemy sprite (%d) in the enemy sprite list.\n", nSprite); 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(); 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++) for (int j = 0; j < 7; j++)
dudeInfo[i].at70[j] = mulscale8(DudeDifficulty[gGameOptions.nDifficulty], dudeInfo[i].startDamage[j]); dudeInfo[i].at70[j] = mulscale8(DudeDifficulty[gGameOptions.nDifficulty], dudeInfo[i].startDamage[j]);
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 (sprite[nSprite].extra <= 0 || sprite[nSprite].extra >= kMaxXSprites) continue;
int nXSprite = pSprite->extra; spritetype *pSprite = &sprite[nSprite]; XSPRITE *pXSprite = &xsprite[pSprite->extra];
dassert(nXSprite > 0 && nXSprite < kMaxXSprites);
XSPRITE *pXSprite = &xsprite[nXSprite]; int nType = pSprite->type - kDudeBase; int seqStartId = dudeInfo[nType].seqStartID;
int nType = pSprite->type-kDudeBase;
int seqStartId = dudeInfo[nType].seqStartID;
if (!IsPlayerSprite(pSprite)) { if (!IsPlayerSprite(pSprite)) {
switch (pSprite->type) { switch (pSprite->type) {
case kDudeModernCustom: case kDudeModernCustom:
case kDudeModernCustomBurning: 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 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->sysData1 = pXSprite->data3; // by NoOne move sndStartId to sysData1, because data3 used by the game;
pXSprite->data3 = 0; pXSprite->data3 = 0;
@ -2758,7 +2743,7 @@ void actInit(bool bSaveLoad) {
fallthrough__; fallthrough__;
default: default:
pSprite->clipdist = dudeInfo[nType].clipdist; pSprite->clipdist = dudeInfo[nType].clipdist;
pSprite->cstat |= 4096 + 256 + 1; pSprite->cstat |= 4096 + CSTAT_SPRITE_BLOCK_HITSCAN + CSTAT_SPRITE_BLOCK;
break; 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. // 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; if (!gModernMap || pXSprite->data4 <= 0) pXSprite->health = dudeInfo[nType].startHealth << 4;
else pXSprite->health = ClipRange(pXSprite->data4 << 4, 1, 65535); 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(); 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; int dist2 = 0x40000+dx*dx+dy*dy+dz*dz;
dassert(dist2 > 0); dassert(dist2 > 0);
a6 = scale(0x40000, a6, dist2); a6 = scale(0x40000, a6, dist2);
if (pSprite->flags & 1) if (pSprite->flags & kPhysMove) {
{
int mass = 0; int mass = 0;
if (IsDudeSprite(pSprite)) { if (IsDudeSprite(pSprite)) {
mass = dudeInfo[pSprite->type - kDudeBase].mass; 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) else if (pSprite->type >= kThingBase && pSprite->type < kThingMax)
mass = thingInfo[pSprite->type - kThingBase].at2; mass = thingInfo[pSprite->type - kThingBase].mass;
else 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; int size = (tilesiz[pSprite->picnum].x*pSprite->xrepeat*tilesiz[pSprite->picnum].y*pSprite->yrepeat)>>1;
dassert(mass > 0); dassert(mass > 0);
@ -2814,6 +2799,7 @@ void ConcussSprite(int a1, spritetype *pSprite, int x, int y, int z, int a6)
yvel[nSprite] += dy; yvel[nSprite] += dy;
zvel[nSprite] += dz; zvel[nSprite] += dz;
} }
actDamageSprite(a1, pSprite, DAMAGE_TYPE_3, a6); actDamageSprite(a1, pSprite, DAMAGE_TYPE_3, a6);
} }
@ -3248,15 +3234,18 @@ void actKillDude(int nKillerSprite, spritetype *pSprite, DAMAGE_TYPE damageType,
if (pXSprite->dropMsg > 0) if (pXSprite->dropMsg > 0)
actDropObject(pSprite, pXSprite->dropMsg); actDropObject(pSprite, pXSprite->dropMsg);
int nRand = Random(100);
switch (pSprite->type) { switch (pSprite->type) {
case kDudeCultistTommy: case kDudeCultistTommy: {
int nRand = Random(100);
if (nRand < 10) actDropObject(pSprite, kItemWeaponTommygun); if (nRand < 10) actDropObject(pSprite, kItemWeaponTommygun);
else if (nRand < 50) actDropObject(pSprite, kItemAmmoTommygunFew); else if (nRand < 50) actDropObject(pSprite, kItemAmmoTommygunFew);
}
break; break;
case kDudeCultistShotgun: case kDudeCultistShotgun: {
int nRand = Random(100);
if (nRand <= 10) actDropObject(pSprite, kItemWeaponSawedoff); if (nRand <= 10) actDropObject(pSprite, kItemWeaponSawedoff);
else if (nRand <= 50) actDropObject(pSprite, kItemAmmoSawedoffFew); else if (nRand <= 50) actDropObject(pSprite, kItemAmmoSawedoffFew);
}
break; break;
} }
@ -3657,91 +3646,76 @@ void actKillDude(int nKillerSprite, spritetype *pSprite, DAMAGE_TYPE damageType,
actPostSprite(pSprite->index, kStatThing); 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); 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; return 0;
int nXSprite = pSprite->extra;
if (nXSprite <= 0) XSPRITE *pXSprite = &xsprite[pSprite->extra];
return 0;
dassert(nXSprite > 0 && nXSprite < kMaxXSprites);
XSPRITE *pXSprite = &xsprite[nXSprite];
dassert(pXSprite->reference == pSprite->index);
if ((pXSprite->health == 0 && pSprite->statnum != kStatDude) || pXSprite->locked) if ((pXSprite->health == 0 && pSprite->statnum != kStatDude) || pXSprite->locked)
return 0; return 0;
if (nSource == -1)
if (nSource == -1)
nSource = pSprite->index; nSource = pSprite->index;
PLAYER *pSourcePlayer = NULL; PLAYER *pSourcePlayer = NULL;
if (IsPlayerSprite(&sprite[nSource])) if (IsPlayerSprite(&sprite[nSource])) pSourcePlayer = &gPlayer[sprite[nSource].type - kDudePlayer1];
pSourcePlayer = &gPlayer[sprite[nSource].type-kDudePlayer1]; if (!gGameOptions.bFriendlyFire && IsTargetTeammate(pSourcePlayer, pSprite)) return 0;
if (!gGameOptions.bFriendlyFire && IsTargetTeammate(pSourcePlayer, pSprite))
return 0; switch (pSprite->statnum) {
switch (pSprite->statnum) case kStatDude: {
{ if (!IsDudeSprite(pSprite))
case kStatDude: 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 (pSprite->type < kDudeBase || pSprite->type >= kDudeMax)
{ if (!nDamageFactor) return 0;
sprintf(buffer, "Bad Dude Failed: initial=%d type=%d %s\n", (int)pSprite->inittype, (int)pSprite->type, (int)(pSprite->flags&16) ? "RESPAWN" : "NORMAL"); else if (nDamageFactor != 256)
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)
damage = mulscale8(damage, nDamageFactor); damage = mulscale8(damage, nDamageFactor);
if (!IsPlayerSprite(pSprite))
{ if (!IsPlayerSprite(pSprite)) {
if (!pXSprite->health)
return 0; if (pXSprite->health <= 0) return 0;
damage = aiDamageSprite(pSprite, pXSprite, nSource, damageType, damage); damage = aiDamageSprite(pSprite, pXSprite, nSource, damageType, damage);
if (!pXSprite->health) if (pXSprite->health <= 0)
{ actKillDude(nSource, pSprite, ((damageType == DAMAGE_TYPE_3 && damage < 160) ? DAMAGE_TYPE_0 : damageType), damage);
if (damageType == DAMAGE_TYPE_3 && damage < 160)
damageType = DAMAGE_TYPE_0; } else {
actKillDude(nSource, pSprite, damageType, damage);
} PLAYER *pPlayer = &gPlayer[pSprite->type - kDudePlayer1];
}
else
{
PLAYER *pPlayer = &gPlayer[pSprite->type-kDudePlayer1];
if (pXSprite->health > 0 || playerSeqPlaying(pPlayer, 16)) if (pXSprite->health > 0 || playerSeqPlaying(pPlayer, 16))
damage = playerDamageSprite(nSource, pPlayer, damageType, damage); damage = playerDamageSprite(nSource, pPlayer, damageType, damage);
}
} }
break; break;
}
case kStatThing: case kStatThing:
dassert(pSprite->type >= kThingBase && pSprite->type < kThingMax); dassert(pSprite->type >= kThingBase && pSprite->type < kThingMax);
int nType = pSprite->type-kThingBase; int nType = pSprite->type - kThingBase; int nDamageFactor = thingInfo[nType].at17[damageType];
int nDamageFactor = thingInfo[nType].at17[damageType];
if (!nDamageFactor) if (!nDamageFactor) return 0;
return 0; else if (nDamageFactor != 256)
if (nDamageFactor != 256)
damage = mulscale8(damage, nDamageFactor); damage = mulscale8(damage, nDamageFactor);
pXSprite->health = ClipLow(pXSprite->health-damage, 0);
if (!pXSprite->health) pXSprite->health = ClipLow(pXSprite->health - damage, 0);
{ if (pXSprite->health <= 0) {
if (pSprite->type == kThingDroppedLifeLeech || pSprite->type == kModernThingEnemyLifeLeech) switch (pSprite->type) {
{ case kThingDroppedLifeLeech:
case kModernThingEnemyLifeLeech:
GibSprite(pSprite, GIBTYPE_14, NULL, NULL); GibSprite(pSprite, GIBTYPE_14, NULL, NULL);
pXSprite->data1 = 0; pXSprite->data1 = pXSprite->data2 = pXSprite->data3 = pXSprite->DudeLockout = 0;
pXSprite->data2 = 0; pXSprite->stateTimer = pXSprite->data4 = pXSprite->isTriggered = 0;
pXSprite->data3 = 0;
pXSprite->stateTimer = 0;
pXSprite->data4 = 0;
pXSprite->isTriggered = 0;
pXSprite->DudeLockout = 0;
if (pSprite->owner >= 0 && sprite[pSprite->owner].type == kDudeModernCustom) 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); trTriggerSprite(pSprite->index, pXSprite, kCmdOff);
switch (pSprite->type) { switch (pSprite->type) {
case kThingObjectGib: case kThingObjectGib:
case kThingObjectExplode: case kThingObjectExplode:
@ -3788,7 +3762,8 @@ int actDamageSprite(int nSource, spritetype *pSprite, DAMAGE_TYPE damageType, in
} }
break; 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) 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) { switch (hitCode) {
case 0: case 0:
case 4: case 4:
if (!pWallHit) break; if (pWallHit) {
spritetype* pFX = gFX.fxSpawn(FX_52, pMissile->sectnum, pMissile->x, pMissile->y, pMissile->z, 0); spritetype* pFX = gFX.fxSpawn(FX_52, pMissile->sectnum, pMissile->x, pMissile->y, pMissile->z, 0);
if (pFX) pFX->ang = (GetWallAngle(nWallHit) + 512) & 2047; if (pFX) pFX->ang = (GetWallAngle(nWallHit) + 512) & 2047;
} }
break;
}
GibSprite(pMissile, GIBTYPE_24, NULL, NULL); GibSprite(pMissile, GIBTYPE_24, NULL, NULL);
actPostSprite(pMissile->index, kStatFree); actPostSprite(pMissile->index, kStatFree);
break; break;
@ -4202,9 +4179,9 @@ void ProcessTouchObjects(spritetype *pSprite, int nXSprite)
{ {
int nType = pSprite2->type-kThingBase; int nType = pSprite2->type-kThingBase;
THINGINFO *pThingInfo = &thingInfo[nType]; THINGINFO *pThingInfo = &thingInfo[nType];
if (pThingInfo->at5&1) if (pThingInfo->flags&1)
pSprite2->flags |= 1; pSprite2->flags |= 1;
if (pThingInfo->at5&2) if (pThingInfo->flags&2)
pSprite2->flags |= 4; pSprite2->flags |= 4;
// Inlined ? // Inlined ?
xvel[pSprite2->index] += mulscale(4, pSprite2->x-sprite[nSprite].x, 2); xvel[pSprite2->index] += mulscale(4, pSprite2->x-sprite[nSprite].x, 2);
@ -5454,7 +5431,7 @@ void actExplodeSprite(spritetype *pSprite)
{ {
XSPRITE *pXSprite = &xsprite[nXSprite]; XSPRITE *pXSprite = &xsprite[nXSprite];
pXSprite->state = 1; pXSprite->state = 1;
pXSprite->health = thingInfo[0].at0<<4; pXSprite->health = thingInfo[0].health<<4;
} }
else else
actPostSprite(pSprite->index, kStatFree); actPostSprite(pSprite->index, kStatFree);
@ -5793,9 +5770,9 @@ void actProcessSprites(void)
{ {
int nType = pSprite->type - kThingBase; int nType = pSprite->type - kThingBase;
THINGINFO *pThingInfo = &thingInfo[nType]; THINGINFO *pThingInfo = &thingInfo[nType];
if (pThingInfo->at5 & 1) if (pThingInfo->flags & 1)
pSprite->flags |= 1; pSprite->flags |= 1;
if (pThingInfo->at5 & 2) if (pThingInfo->flags & 2)
pSprite->flags |= 4; pSprite->flags |= 4;
} }
if (pSprite->flags&3) 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); dassert(nXThing > 0 && nXThing < kMaxXSprites);
XSPRITE *pXThing = &xsprite[nXThing]; XSPRITE *pXThing = &xsprite[nXThing];
THINGINFO *pThingInfo = &thingInfo[nType]; THINGINFO *pThingInfo = &thingInfo[nType];
pXThing->health = pThingInfo->at0<<4; pXThing->health = pThingInfo->health<<4;
pSprite->clipdist = pThingInfo->at4; pSprite->clipdist = pThingInfo->clipdist;
pSprite->flags = pThingInfo->at5; pSprite->flags = pThingInfo->flags;
if (pSprite->flags & 2) if (pSprite->flags & 2)
pSprite->flags |= 4; pSprite->flags |= 4;
pSprite->cstat |= pThingInfo->atf; 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) if (pSprite->statnum == kStatThing)
{ {
int t = thingInfo[pSprite->type-kThingBase].at2; int t = thingInfo[pSprite->type-kThingBase].mass;
if (t > 0 && pVectorData->at5) if (t > 0 && pVectorData->at5)
{ {
int t2 = divscale(pVectorData->at5, t, 8); int t2 = divscale(pVectorData->at5, t, 8);
@ -7129,7 +7106,7 @@ void TreeToGibCallback(int, int nXSprite)
pXSprite->data1 = 15; pXSprite->data1 = 15;
pXSprite->data2 = 0; pXSprite->data2 = 0;
pXSprite->data3 = 0; pXSprite->data3 = 0;
pXSprite->health = thingInfo[17].at0; pXSprite->health = thingInfo[17].health;
pXSprite->data4 = 312; pXSprite->data4 = 312;
pSprite->cstat |= 257; pSprite->cstat |= 257;
} }
@ -7143,7 +7120,7 @@ void DudeToGibCallback1(int, int nXSprite)
pXSprite->data1 = 8; pXSprite->data1 = 8;
pXSprite->data2 = 0; pXSprite->data2 = 0;
pXSprite->data3 = 0; pXSprite->data3 = 0;
pXSprite->health = thingInfo[26].at0; pXSprite->health = thingInfo[26].health;
pXSprite->data4 = 319; pXSprite->data4 = 319;
pXSprite->triggerOnce = 0; pXSprite->triggerOnce = 0;
pXSprite->isTriggered = 0; pXSprite->isTriggered = 0;
@ -7161,7 +7138,7 @@ void DudeToGibCallback2(int, int nXSprite)
pXSprite->data1 = 3; pXSprite->data1 = 3;
pXSprite->data2 = 0; pXSprite->data2 = 0;
pXSprite->data3 = 0; pXSprite->data3 = 0;
pXSprite->health = thingInfo[26].at0; pXSprite->health = thingInfo[26].health;
pXSprite->data4 = 319; pXSprite->data4 = 319;
pXSprite->triggerOnce = 0; pXSprite->triggerOnce = 0;
pXSprite->isTriggered = 0; pXSprite->isTriggered = 0;

View file

@ -69,10 +69,10 @@ enum VECTOR_TYPE {
struct THINGINFO struct THINGINFO
{ {
short at0; // health short health; // health
short at2; // mass short mass; // mass
unsigned char at4; // clipdist unsigned char clipdist; // clipdist
short at5; // flags short flags; // flags
int at7; // elasticity int at7; // elasticity
int atb; // damage resistance int atb; // damage resistance
short atf; // cstat short atf; // cstat
@ -191,7 +191,6 @@ extern int gDudeDrag;
extern short gAffectedSectors[kMaxSectors]; extern short gAffectedSectors[kMaxSectors];
extern short gAffectedXWalls[kMaxXWalls]; extern short gAffectedXWalls[kMaxXWalls];
inline bool IsPlayerSprite(spritetype *pSprite) inline bool IsPlayerSprite(spritetype *pSprite)
{ {
if (pSprite->type >= kDudePlayer1 && pSprite->type <= kDudePlayer8) if (pSprite->type >= kDudePlayer1 && pSprite->type <= kDudePlayer8)

View file

@ -121,10 +121,15 @@ static void SpidBiteSeqCallback(int, int nXSprite)
actFireVector(pSprite, 0, 0, dx, dy, dz, VECTOR_TYPE_17); actFireVector(pSprite, 0, 0, dx, dy, dz, VECTOR_TYPE_17);
sub_70D30(pXTarget, 8, 16); sub_70D30(pXTarget, 8, 16);
break; 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, 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); sub_70D30(pXTarget, 8, 16);
}
break; break;
} }
} }

View file

@ -27,6 +27,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "fx_man.h" #include "fx_man.h"
#include "common_game.h" #include "common_game.h"
//#include "blood.h" //#include "blood.h"
#include "view.h"
#include "config.h" #include "config.h"
#include "db.h" #include "db.h"
#include "player.h" #include "player.h"
@ -116,49 +117,52 @@ void ambInit(void)
{ {
ambKillAll(); ambKillAll();
memset(ambChannels, 0, sizeof(ambChannels)); memset(ambChannels, 0, sizeof(ambChannels));
for (int nSprite = headspritestat[kStatAmbience]; nSprite >= 0; nSprite = nextspritestat[nSprite]) for (int nSprite = headspritestat[kStatAmbience]; nSprite >= 0; nSprite = nextspritestat[nSprite]) {
{ if (sprite[nSprite].extra <= 0 || sprite[nSprite].extra >= kMaxXSprites) continue;
spritetype *pSprite = &sprite[nSprite];
int nXSprite = pSprite->extra; XSPRITE *pXSprite = &xsprite[sprite[nSprite].extra];
if (nXSprite > 0 && nXSprite < kMaxXSprites) if (pXSprite->data1 >= pXSprite->data2) continue;
{
XSPRITE *pXSprite = &xsprite[nXSprite]; int i; AMB_CHANNEL *pChannel = ambChannels;
if (pXSprite->data1 < pXSprite->data2) for (i = 0; i < nAmbChannels; i++, pChannel++)
{ if (pXSprite->data3 == pChannel->at8) break;
int i;
AMB_CHANNEL *pChannel = ambChannels; if (i == nAmbChannels) {
for (i = 0; i < nAmbChannels; i++, pChannel++)
if (pXSprite->data3 == pChannel->at8) if (i >= kMaxAmbChannel) {
break; sprite[nSprite].owner = -1;
if (i == nAmbChannels) continue;
{
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;
} }
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;
} }
} }

View file

@ -629,6 +629,10 @@ void StartLevel(GAMEOPTIONS *gameOptions)
case kModernDudeTargetChanger: case kModernDudeTargetChanger:
changespritestat(i, kStatModernDudeTargetChanger); changespritestat(i, kStatModernDudeTargetChanger);
break; break;
// add statnum for faster searching of already enabled qav players
case kModernPlayQAV:
changespritestat(i, kStatModernPlayQAV);
break;
// remove kStatItem status from random item generators // remove kStatItem status from random item generators
case kModernRandom: case kModernRandom:
case kModernRandom2: case kModernRandom2:

View file

@ -227,67 +227,66 @@ void fxDynPuff(int nSprite) // 8
void Respawn(int nSprite) // 9 void Respawn(int nSprite) // 9
{ {
spritetype *pSprite = &sprite[nSprite]; spritetype *pSprite = &sprite[nSprite];
int nXSprite = pSprite->extra; dassert(pSprite->extra > 0 && pSprite->extra < kMaxXSprites);
dassert(nXSprite > 0 && nXSprite < kMaxXSprites); XSPRITE *pXSprite = &xsprite[pSprite->extra];
XSPRITE *pXSprite = &xsprite[nXSprite];
if (pSprite->statnum != kStatRespawn && pSprite->statnum != kStatThing) if (pSprite->statnum != kStatRespawn && pSprite->statnum != kStatThing) {
ThrowError("Sprite %d is not on Respawn or Thing list\n", nSprite); viewSetSystemMessage("Sprite #%d is not on Respawn or Thing list\n", nSprite);
if (!(pSprite->flags&16)) return;
ThrowError("Sprite %d does not have the respawn attribute\n", nSprite); } else if (!(pSprite->flags & kHitagRespawn)) {
switch (pXSprite->respawnPending) viewSetSystemMessage("Sprite #%d does not have the respawn attribute\n", nSprite);
{ return;
case 1:
{
int nTime = mulscale16(actGetRespawnTime(pSprite), 0x4000);
pXSprite->respawnPending = 2;
evPost(nSprite, 3, nTime, kCallbackRespawn);
break;
} }
case 2:
{ switch (pXSprite->respawnPending) {
int nTime = mulscale16(actGetRespawnTime(pSprite), 0x2000); case 1: {
pXSprite->respawnPending = 3; int nTime = mulscale16(actGetRespawnTime(pSprite), 0x4000);
evPost(nSprite, 3, nTime, kCallbackRespawn); pXSprite->respawnPending = 2;
break; 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;
} }
if (pSprite->type == kThingTNTBarrel) case 2: {
{ int nTime = mulscale16(actGetRespawnTime(pSprite), 0x2000);
pSprite->cstat |= CSTAT_SPRITE_BLOCK | CSTAT_SPRITE_BLOCK_HITSCAN; pXSprite->respawnPending = 3;
pSprite->cstat &= (unsigned short)~CSTAT_SPRITE_INVISIBLE; 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;
} }
} }

View file

@ -51,7 +51,7 @@ enum CALLBACK_ID {
kCallbackDropVoodoo = 21, // unused kCallbackDropVoodoo = 21, // unused
kCallbackMissileBurst = 22, // by NoOne kCallbackMissileBurst = 22, // by NoOne
kCallbackMissileSpriteBlock = 23, // by NoOne kCallbackMissileSpriteBlock = 23, // by NoOne
kCallbackMax = 24 kCallbackMax = 24,
}; };
extern void (*gCallback[kCallbackMax])(int); extern void (*gCallback[kCallbackMax])(int);

View file

@ -99,7 +99,8 @@ void QuitGame(void);
#define kStatFlare 14 #define kStatFlare 14
#define kStatDebris 15 #define kStatDebris 15
#define kStatPathMarker 16 #define kStatPathMarker 16
#define kStatModernDudeTargetChanger 20 #define kStatModernDudeTargetChanger 20 // gModernMap only
#define kStatModernPlayQAV 21 // gModernMap only
#define kStatFree 1024 #define kStatFree 1024
#define kLensSize 80 #define kLensSize 80
@ -159,7 +160,8 @@ enum {
kModernObjDataAccumulator = 37, kModernObjDataAccumulator = 37,
kModernEffectSpawner = 38, kModernEffectSpawner = 38,
kModernWindGenerator = 39, kModernWindGenerator = 39,
kModernConcussSprite = 712, kModernConcussSprite = 712, /// WIP
kModernPlayQAV = 713, /// WIP
// decorations // decorations
kDecorationTorch = 30, kDecorationTorch = 30,

View file

@ -158,19 +158,18 @@ void CKillMgr::sub_2641C(void)
for (int nSprite = headspritestat[kStatDude]; nSprite >= 0; nSprite = nextspritestat[nSprite]) { for (int nSprite = headspritestat[kStatDude]; nSprite >= 0; nSprite = nextspritestat[nSprite]) {
spritetype *pSprite = &sprite[nSprite]; spritetype *pSprite = &sprite[nSprite];
if (pSprite->type < kDudeBase || pSprite->type >= kDudeMax) if (IsDudeSprite(pSprite)) {
ThrowError("Non-enemy sprite (%d) in the enemy sprite list.", nSprite); if (pSprite->statnum == kStatDude) {
switch (pSprite->type) {
if (pSprite->statnum == kStatDude) { case kDudeBat:
switch (pSprite->type) { case kDudeRat:
case kDudeBat: case kDudeBurningInnocent:
case kDudeRat: case kDudeInnocent:
case kDudeBurningInnocent: return;
case kDudeInnocent: }
return;
}
at0++; at0++;
}
} }
} }
@ -229,22 +228,20 @@ void CSecretMgr::SetCount(int nCount)
void CSecretMgr::Found(int nType) void CSecretMgr::Found(int nType)
{ {
if (nType < 0) if (nType == 0) at4++;
ThrowError("Invalid secret type %d triggered.", nType); else if (nType < 0) {
if (nType == 0) viewSetSystemMessage("Invalid secret type %d triggered.", nType);
at4++; return;
else } else at8++;
at8++;
if (gGameOptions.nGameType == 0) if (gGameOptions.nGameType == 0) {
{ switch (Random(2)) {
switch (Random(2)) case 0:
{ viewSetMessage("A secret is revealed.", 0, MESSAGE_PRIORITY_SECRET);
case 0: break;
viewSetMessage("A secret is revealed.", 0, MESSAGE_PRIORITY_SECRET); case 1:
break; viewSetMessage("You found a secret.", 0, MESSAGE_PRIORITY_SECRET);
case 1: break;
viewSetMessage("You found a secret.", 0, MESSAGE_PRIORITY_SECRET);
break;
} }
} }
} }

View file

@ -82,32 +82,25 @@ RXBUCKET rxBucket[kMaxChannels+1];
int GetBucketChannel(const RXBUCKET *pRX) int GetBucketChannel(const RXBUCKET *pRX)
{ {
switch (pRX->type) switch (pRX->type) {
{ case 6: {
case 6: int nIndex = pRX->index;
{ int nXIndex = sector[nIndex].extra;
int nIndex = pRX->index; dassert(nXIndex > 0);
int nXIndex = sector[nIndex].extra; return xsector[nXIndex].rxID;
dassert(nXIndex > 0); }
return xsector[nXIndex].rxID; case 0: {
} int nIndex = pRX->index;
case 0: int nXIndex = wall[nIndex].extra;
{ dassert(nXIndex > 0);
int nIndex = pRX->index; return xwall[nXIndex].rxID;
int nXIndex = wall[nIndex].extra; }
dassert(nXIndex > 0); case 3: {
return xwall[nXIndex].rxID; int nIndex = pRX->index;
} int nXIndex = sprite[nIndex].extra;
case 3: dassert(nXIndex > 0);
{ return xsprite[nXIndex].rxID;
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;
} }
return 0; return 0;
} }

View file

@ -38,6 +38,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "gameutil.h" #include "gameutil.h"
#include "actor.h" #include "actor.h"
#include "tile.h" #include "tile.h"
#include "view.h"
BEGIN_BLD_NS BEGIN_BLD_NS
@ -378,11 +379,14 @@ void UnlockInstance(SEQINST *pInst)
void seqSpawn(int a1, int a2, int a3, int a4) void seqSpawn(int a1, int a2, int a3, int a4)
{ {
SEQINST *pInst = GetInstance(a2, a3); SEQINST *pInst = GetInstance(a2, a3);
if (!pInst) if (!pInst) return;
return;
DICTNODE *hSeq = gSysRes.Lookup(a1, "SEQ"); DICTNODE *hSeq = gSysRes.Lookup(a1, "SEQ");
if (!hSeq) if (!hSeq) {
ThrowError("Missing sequence #%d", a1); viewSetSystemMessage("Missing sequence #%d", a1);
return;
}
int i = activeCount; int i = activeCount;
if (pInst->at13) if (pInst->at13)
{ {
@ -577,8 +581,10 @@ void SeqLoadSave::Load(void)
{ {
int nSeq = pInst->at8; int nSeq = pInst->at8;
DICTNODE *hSeq = gSysRes.Lookup(nSeq, "SEQ"); DICTNODE *hSeq = gSysRes.Lookup(nSeq, "SEQ");
if (!hSeq) if (!hSeq) {
ThrowError("Missing sequence #%d", nSeq); viewSetSystemMessage("Missing sequence #%d", nSeq);
continue;
}
Seq *pSeq = (Seq*)gSysRes.Lock(hSeq); Seq *pSeq = (Seq*)gSysRes.Lock(hSeq);
if (memcmp(pSeq->signature, "SEQ\x1a", 4) != 0) if (memcmp(pSeq->signature, "SEQ\x1a", 4) != 0)
ThrowError("Invalid sequence %d", nSeq); ThrowError("Invalid sequence %d", nSeq);

View file

@ -119,18 +119,15 @@ void Calc3DValues(BONKLE *pBonkle)
void sfxPlay3DSound(int x, int y, int z, int soundId, int nSector) void sfxPlay3DSound(int x, int y, int z, int soundId, int nSector)
{ {
if (!SoundToggle) if (!SoundToggle || soundId < 0) return;
return;
if (soundId < 0)
ThrowError("Invalid sound ID");
DICTNODE *hRes = gSoundRes.Lookup(soundId, "SFX"); DICTNODE *hRes = gSoundRes.Lookup(soundId, "SFX");
if (!hRes) if (!hRes)return;
return;
SFX *pEffect = (SFX*)gSoundRes.Load(hRes); SFX *pEffect = (SFX*)gSoundRes.Load(hRes);
hRes = gSoundRes.Lookup(pEffect->rawName, "RAW"); hRes = gSoundRes.Lookup(pEffect->rawName, "RAW");
if (!hRes) if (!hRes) return;
return;
int v1c, v18; int v1c, v18;
v1c = v18 = mulscale16(pEffect->pitch, sndGetRate(pEffect->format)); v1c = v18 = mulscale16(pEffect->pitch, sndGetRate(pEffect->format));
if (nBonkles >= 256) if (nBonkles >= 256)

View file

@ -35,16 +35,19 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "globals.h" #include "globals.h"
#include "resource.h" #include "resource.h"
#include "tile.h" #include "tile.h"
#include "view.h"
BEGIN_BLD_NS BEGIN_BLD_NS
void qloadvoxel(int32_t nVoxel) void qloadvoxel(int32_t nVoxel)
{ {
static int nLastVoxel = 0; static int nLastVoxel = 0;
dassert(nVoxel >= 0 && nVoxel < kMaxVoxels);
DICTNODE *hVox = gSysRes.Lookup(nVoxel, "KVX"); DICTNODE *hVox = gSysRes.Lookup(nVoxel, "KVX");
if (!hVox) if (!hVox) {
ThrowError("Missing voxel #%d", nVoxel); viewSetSystemMessage("Missing voxel #%d (max voxels: %d)", nVoxel, kMaxVoxels);
return;
}
if (!hVox->lockCount) if (!hVox->lockCount)
voxoff[nLastVoxel][0] = 0; voxoff[nLastVoxel][0] = 0;
nLastVoxel = nVoxel; nLastVoxel = nVoxel;

View file

@ -52,6 +52,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "view.h" #include "view.h"
#include "sectorfx.h" #include "sectorfx.h"
#include "messages.h" #include "messages.h"
#include "weapon.h"
BEGIN_BLD_NS BEGIN_BLD_NS
@ -406,10 +407,10 @@ void OperateSprite(int nSprite, XSPRITE *pXSprite, EVENT event)
case kMarkerLowStack: case kMarkerLowStack:
case kMarkerPath: case kMarkerPath:
switch (pXSprite->command) { switch (pXSprite->command) {
case kCmdLink: case kCmdLink:
if (pXSprite->txID <= 0) return; if (pXSprite->txID <= 0) return;
evSend(nSprite, 3, pXSprite->txID, (COMMAND_ID)pXSprite->command); evSend(nSprite, 3, pXSprite->txID, (COMMAND_ID)pXSprite->command);
return; return;
} }
break; // go normal operate switch break; // go normal operate switch
@ -816,6 +817,36 @@ void OperateSprite(int nSprite, XSPRITE *pXSprite, EVENT event)
break; break;
} }
return; 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) { void OperateWall(int nWall, XWALL *pXWall, EVENT event) {
walltype *pWall = &wall[nWall]; walltype *pWall = &wall[nWall];
switch (event.cmd) { switch (event.cmd) {
case kCmdLock: case kCmdLock:
pXWall->locked = 1; pXWall->locked = 1;
@ -1723,28 +1755,30 @@ void OperateWall(int nWall, XWALL *pXWall, EVENT event) {
return; return;
} }
// by NoOne: make 1-Way switch type for walls to work...
if (gModernMap) { if (gModernMap) {
// by NoOne: make 1-Way switch type for walls to work...
switch (pWall->type) { switch (pWall->type) {
case kSwitchOneWay: case kSwitchOneWay:
switch (event.cmd) { switch (event.cmd) {
case kCmdOff: case kCmdOff:
SetWallState(nWall, pXWall, 0); SetWallState(nWall, pXWall, 0);
break; break;
case kCmdOn: case kCmdOn:
SetWallState(nWall, pXWall, 1); SetWallState(nWall, pXWall, 1);
break; break;
default: default:
SetWallState(nWall, pXWall, pXWall->restState ^ 1); SetWallState(nWall, pXWall, pXWall->restState ^ 1);
break; break;
} }
return; return;
default:
break;
} }
} else { }
switch (pWall->type) { switch (pWall->type) {
case kWallGib: case kWallGib:
if (GetWallType(nWall) != pWall->type) break; if (GetWallType(nWall) != pWall->type) break;
char bStatus; char bStatus;
@ -1771,22 +1805,22 @@ void OperateWall(int nWall, XWALL *pXWall, EVENT event) {
} }
} }
return; return;
}
}
switch (event.cmd) {
case kCmdOff:
SetWallState(nWall, pXWall, 0);
break;
case kCmdOn:
SetWallState(nWall, pXWall, 1);
break;
default: default:
SetWallState(nWall, pXWall, pXWall->state ^ 1); switch (event.cmd) {
break; 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) 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 // 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. // when kModernDudeTargetChanger goes to off state, so they won't ignore the world.
void activateDudes(int rx) { void activateDudes(int rx) {

View file

@ -77,6 +77,7 @@ void useTeleportTarget(XSPRITE* pXSource, spritetype* pSprite);
void usePropertiesChanger(XSPRITE* pXSource, short objType, int objIndex); void usePropertiesChanger(XSPRITE* pXSource, short objType, int objIndex);
void TeleFrag(int nKiller, int nSector); void TeleFrag(int nKiller, int nSector);
bool valueIsBetween(int val, int min, int max); bool valueIsBetween(int val, int min, int max);
void disableQAVPlayers(spritetype* pException);
// ------------------------------------------------------- // -------------------------------------------------------

View file

@ -35,5 +35,5 @@ void WeaponLower(PLAYER *pPlayer);
char WeaponUpgrade(PLAYER *pPlayer, char newWeapon); char WeaponUpgrade(PLAYER *pPlayer, char newWeapon);
void WeaponProcess(PLAYER *pPlayer); void WeaponProcess(PLAYER *pPlayer);
void sub_51340(spritetype *pMissile, int a2); void sub_51340(spritetype *pMissile, int a2);
void StartQAV(PLAYER* pPlayer, int nWeaponQAV, int a3 = -1, char a4 = 0);
END_BLD_NS END_BLD_NS