mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-26 11:40:44 +00:00
- MoveMissile + actExplodeSprite.
# Conflicts: # source/games/blood/src/actor.cpp
This commit is contained in:
parent
29c2e68270
commit
ddcb12a8b2
6 changed files with 196 additions and 210 deletions
|
@ -4010,12 +4010,12 @@ static void actImpactMissile(DBloodActor* missileActor, int hitCode)
|
|||
int nDamage = (50 + Random(50)) << 4;
|
||||
actDamageSprite(missileOwner, actorHit, kDamageBullet, nDamage);
|
||||
}
|
||||
actExplodeSprite(pMissile);
|
||||
actExplodeSprite(missileActor);
|
||||
break;
|
||||
|
||||
case kMissileFlareAlt:
|
||||
sfxKill3DSound(pMissile, -1, -1);
|
||||
actExplodeSprite(pMissile);
|
||||
actExplodeSprite(missileActor);
|
||||
break;
|
||||
|
||||
case kMissileFlareRegular:
|
||||
|
@ -4072,7 +4072,7 @@ static void actImpactMissile(DBloodActor* missileActor, int hitCode)
|
|||
break;
|
||||
|
||||
case kMissileFireballCerberus:
|
||||
actExplodeSprite(pMissile);
|
||||
actExplodeSprite(missileActor);
|
||||
if (hitCode == 3 && actorHit && actorHit->hasX())
|
||||
{
|
||||
if ((pSpriteHit->statnum == kStatThing || pSpriteHit->statnum == kStatDude) && pXSpriteHit->burnTime == 0)
|
||||
|
@ -4083,11 +4083,11 @@ static void actImpactMissile(DBloodActor* missileActor, int hitCode)
|
|||
int nDamage = (25 + Random(10)) << 4;
|
||||
actDamageSprite(missileOwner, actorHit, kDamageBullet, nDamage);
|
||||
}
|
||||
actExplodeSprite(pMissile);
|
||||
actExplodeSprite(missileActor);
|
||||
break;
|
||||
|
||||
case kMissileFireballTchernobog:
|
||||
actExplodeSprite(pMissile);
|
||||
actExplodeSprite(missileActor);
|
||||
if (hitCode == 3 && actorHit && actorHit->hasX())
|
||||
{
|
||||
if ((pSpriteHit->statnum == kStatThing || pSpriteHit->statnum == kStatDude) && pXSpriteHit->burnTime == 0)
|
||||
|
@ -4098,7 +4098,7 @@ static void actImpactMissile(DBloodActor* missileActor, int hitCode)
|
|||
int nDamage = (25 + Random(10)) << 4;
|
||||
actDamageSprite(missileOwner, actorHit, kDamageBullet, nDamage);
|
||||
}
|
||||
actExplodeSprite(pMissile);
|
||||
actExplodeSprite(missileActor);
|
||||
break;
|
||||
|
||||
case kMissileEctoSkull:
|
||||
|
@ -5331,63 +5331,53 @@ void MoveDude(DBloodActor* actor)
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
int MoveMissile(spritetype *pSprite)
|
||||
int MoveMissile(DBloodActor* actor)
|
||||
{
|
||||
int nXSprite = pSprite->extra;
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
int vdi = -1;
|
||||
spritetype *pOwner = NULL;
|
||||
auto pSprite = &actor->s();
|
||||
auto pXSprite = &actor->x();
|
||||
auto Owner = actor->GetOwner();
|
||||
int cliptype = -1;
|
||||
int bakCstat = 0;
|
||||
if (pSprite->owner >= 0)
|
||||
spritetype* pOwner = nullptr;
|
||||
if (Owner && Owner->IsDudeActor())
|
||||
{
|
||||
int nOwner = pSprite->owner;
|
||||
pOwner = &sprite[nOwner];
|
||||
if (IsDudeSprite(pOwner))
|
||||
{
|
||||
pOwner = &Owner->s();
|
||||
bakCstat = pOwner->cstat;
|
||||
pOwner->cstat &= ~257;
|
||||
}
|
||||
else
|
||||
pOwner = NULL;
|
||||
}
|
||||
gHitInfo.hitsect = -1;
|
||||
gHitInfo.hitwall = -1;
|
||||
gHitInfo.hitsprite = -1;
|
||||
if (pSprite->type == kMissileFlameSpray)
|
||||
actAirDrag(&bloodActors[pSprite->index], 0x1000);
|
||||
int nSprite = pSprite->index;
|
||||
if (pXSprite->target != -1 && (xvel[nSprite] || yvel[nSprite] || zvel[nSprite]))
|
||||
if (pSprite->type == kMissileFlameSpray) actAirDrag(actor, 0x1000);
|
||||
|
||||
if (pXSprite->target != -1 && (actor->xvel() || actor->yvel() || actor->zvel()))
|
||||
{
|
||||
spritetype *pTarget = &sprite[pXSprite->target];
|
||||
XSPRITE *pXTarget;
|
||||
if (pTarget->extra > 0)
|
||||
pXTarget = &xsprite[pTarget->extra];
|
||||
else
|
||||
pXTarget = NULL;
|
||||
auto target = actor->GetTarget();
|
||||
spritetype* pTarget = &target->s();
|
||||
XSPRITE* pXTarget = target->hasX() ? &target->x() : nullptr;
|
||||
|
||||
if (pTarget->statnum == kStatDude && pXTarget && pXTarget->health > 0)
|
||||
{
|
||||
int nTargetAngle = getangle(-(pTarget->y-pSprite->y), pTarget->x-pSprite->x);
|
||||
int nTargetAngle = getangle(-(pTarget->y - pSprite->y), pTarget->x - pSprite->x);
|
||||
int vx = missileInfo[pSprite->type - kMissileBase].velocity;
|
||||
int vy = 0;
|
||||
RotatePoint(&vx, &vy, (nTargetAngle+1536)&2047, 0, 0);
|
||||
xvel[nSprite] = vx;
|
||||
yvel[nSprite] = vy;
|
||||
int dx = pTarget->x-pSprite->x;
|
||||
int dy = pTarget->y-pSprite->y;
|
||||
int dz = pTarget->z-pSprite->z;
|
||||
// Inlined
|
||||
int vax = dz/10;
|
||||
if (pTarget->z < pSprite->z)
|
||||
vax = -vax;
|
||||
zvel[nSprite] += vax;
|
||||
ksqrt(dx*dx+dy*dy+dz*dz);
|
||||
RotatePoint(&vx, &vy, (nTargetAngle + 1536) & 2047, 0, 0);
|
||||
actor->xvel() = vx;
|
||||
actor->yvel() = vy;
|
||||
int dx = pTarget->x - pSprite->x;
|
||||
int dy = pTarget->y - pSprite->y;
|
||||
int dz = pTarget->z - pSprite->z;
|
||||
|
||||
int deltaz = dz / 10;
|
||||
if (pTarget->z < pSprite->z) deltaz = -deltaz;
|
||||
actor->zvel() += deltaz;
|
||||
}
|
||||
}
|
||||
int vx = xvel[nSprite]>>12;
|
||||
int vy = yvel[nSprite]>>12;
|
||||
int vz = zvel[nSprite]>>8;
|
||||
int vx = actor->xvel() >> 12;
|
||||
int vy = actor->yvel() >> 12;
|
||||
int vz = actor->zvel() >> 8;
|
||||
int top, bottom;
|
||||
GetSpriteExtents(pSprite, &top, &bottom);
|
||||
GetActorExtents(actor, &top, &bottom);
|
||||
int i = 1;
|
||||
const int bakCompat = enginecompatibility_mode;
|
||||
const bool isFlameSprite = (pSprite->type == kMissileFlameSpray || pSprite->type == kMissileFlameHound); // do not use accurate clipmove for flame based sprites (changes damage too much)
|
||||
|
@ -5404,95 +5394,88 @@ int MoveMissile(spritetype *pSprite)
|
|||
enginecompatibility_mode = ENGINECOMPATIBILITY_NONE; // improved clipmove accuracy
|
||||
pSprite->cstat &= ~257; // remove self collisions for accurate clipmove
|
||||
}
|
||||
int vdx = ClipMove(&x, &y, &z, &nSector2, vx, vy, pSprite->clipdist<<2, (z-top)/4, (bottom-z)/4, CLIPMASK0);
|
||||
Collision clipmoveresult = ClipMove(&x, &y, &z, &nSector2, vx, vy, pSprite->clipdist << 2, (z - top) / 4, (bottom - z) / 4, CLIPMASK0);
|
||||
enginecompatibility_mode = bakCompat; // restore
|
||||
pSprite->cstat = bakSpriteCstat;
|
||||
clipmoveboxtracenum = 3;
|
||||
short nSector = nSector2;
|
||||
if (nSector2 < 0)
|
||||
{
|
||||
vdi = -1;
|
||||
cliptype = -1;
|
||||
break;
|
||||
}
|
||||
if (vdx)
|
||||
if (clipmoveresult.type == kHitSprite)
|
||||
{
|
||||
int nHitSprite = vdx & 0x3fff;
|
||||
if ((vdx&0xc000) == 0xc000)
|
||||
{
|
||||
gHitInfo.hitsprite = nHitSprite;
|
||||
vdi = 3;
|
||||
gHitInfo.hitsprite = clipmoveresult.legacyVal;
|
||||
cliptype = 3;
|
||||
}
|
||||
else if ((vdx & 0xc000) == 0x8000)
|
||||
else if (clipmoveresult.type == kHitWall)
|
||||
{
|
||||
gHitInfo.hitwall = nHitSprite;
|
||||
if (wall[nHitSprite].nextsector == -1)
|
||||
vdi = 0;
|
||||
gHitInfo.hitwall = clipmoveresult.index;
|
||||
if (wall[clipmoveresult.index].nextsector == -1) cliptype = 0;
|
||||
else
|
||||
{
|
||||
int32_t fz, cz;
|
||||
getzsofslope(wall[nHitSprite].nextsector, x, y, &cz, &fz);
|
||||
if (z <= cz || z >= fz)
|
||||
vdi = 0;
|
||||
else
|
||||
vdi = 4;
|
||||
getzsofslope(wall[clipmoveresult.index].nextsector, x, y, &cz, &fz);
|
||||
if (z <= cz || z >= fz) cliptype = 0;
|
||||
else cliptype = 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (vdi == 4)
|
||||
if (cliptype == 4)
|
||||
{
|
||||
walltype *pWall = &wall[gHitInfo.hitwall];
|
||||
walltype* pWall = &wall[gHitInfo.hitwall];
|
||||
if (pWall->extra > 0)
|
||||
{
|
||||
XWALL *pXWall = &xwall[pWall->extra];
|
||||
XWALL* pXWall = &xwall[pWall->extra];
|
||||
if (pXWall->triggerVector)
|
||||
{
|
||||
trTriggerWall(gHitInfo.hitwall, pXWall, kCmdWallImpact);
|
||||
if (!(pWall->cstat&64))
|
||||
if (!(pWall->cstat & 64))
|
||||
{
|
||||
vdi = -1;
|
||||
cliptype = -1;
|
||||
if (i-- > 0)
|
||||
continue;
|
||||
vdi = 0;
|
||||
cliptype = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (vdi >= 0 && vdi != 3)
|
||||
if (cliptype >= 0 && cliptype != 3)
|
||||
{
|
||||
int nAngle = getangle(xvel[nSprite], yvel[nSprite]);
|
||||
int nAngle = getangle(actor->xvel(), actor->yvel());
|
||||
x -= MulScale(Cos(nAngle), 16, 30);
|
||||
y -= MulScale(Sin(nAngle), 16, 30);
|
||||
int nVel = approxDist(xvel[nSprite], yvel[nSprite]);
|
||||
vz -= scale(0x100, zvel[nSprite], nVel);
|
||||
int nVel = approxDist(actor->xvel(), actor->yvel());
|
||||
vz -= scale(0x100, actor->zvel(), nVel);
|
||||
updatesector(x, y, &nSector);
|
||||
nSector2 = nSector;
|
||||
}
|
||||
int ceilZ, ceilHit, floorZ, floorHit;
|
||||
GetZRangeAtXYZ(x, y, z, nSector2, &ceilZ, &ceilHit, &floorZ, &floorHit, pSprite->clipdist<<2, CLIPMASK0);
|
||||
GetSpriteExtents(pSprite, &top, &bottom);
|
||||
GetZRangeAtXYZ(x, y, z, nSector2, &ceilZ, &ceilHit, &floorZ, &floorHit, pSprite->clipdist << 2, CLIPMASK0);
|
||||
GetActorExtents(actor, &top, &bottom);
|
||||
top += vz;
|
||||
bottom += vz;
|
||||
if (bottom >= floorZ)
|
||||
{
|
||||
gSpriteHit[nXSprite].florhit = floorHit;
|
||||
vz += floorZ-bottom;
|
||||
vdi = 2;
|
||||
actor->hit().florhit = floorHit;
|
||||
vz += floorZ - bottom;
|
||||
cliptype = 2;
|
||||
}
|
||||
if (top <= ceilZ)
|
||||
{
|
||||
gSpriteHit[nXSprite].ceilhit = ceilHit;
|
||||
vz += ClipLow(ceilZ-top, 0);
|
||||
vdi = 1;
|
||||
actor->hit().ceilhit = ceilHit;
|
||||
vz += ClipLow(ceilZ - top, 0);
|
||||
cliptype = 1;
|
||||
}
|
||||
pSprite->x = x;
|
||||
pSprite->y = y;
|
||||
pSprite->z = z+vz;
|
||||
pSprite->z = z + vz;
|
||||
updatesector(x, y, &nSector);
|
||||
if (nSector >= 0 && nSector != pSprite->sectnum)
|
||||
{
|
||||
assert(nSector >= 0 && nSector < kMaxSectors);
|
||||
ChangeSpriteSect(nSprite, nSector);
|
||||
ChangeSpriteSect(pSprite->index, nSector);
|
||||
}
|
||||
CheckLink(pSprite);
|
||||
gHitInfo.hitsect = pSprite->sectnum;
|
||||
|
@ -5501,110 +5484,120 @@ int MoveMissile(spritetype *pSprite)
|
|||
gHitInfo.hitz = pSprite->z;
|
||||
break;
|
||||
}
|
||||
if (pOwner)
|
||||
pOwner->cstat = bakCstat;
|
||||
return vdi;
|
||||
if (pOwner) pOwner->cstat = bakCstat;
|
||||
|
||||
return cliptype;
|
||||
}
|
||||
|
||||
void actExplodeSprite(spritetype *pSprite)
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void actExplodeSprite(DBloodActor* actor)
|
||||
{
|
||||
int nXSprite = pSprite->extra;
|
||||
if (nXSprite <= 0 || nXSprite >= kMaxXSprites)
|
||||
return;
|
||||
if (pSprite->statnum == kStatExplosion)
|
||||
return;
|
||||
if (!actor->hasX()) return;
|
||||
auto pSprite = &actor->s();
|
||||
auto pXSprite = &actor->x();
|
||||
//auto Owner = actor->GetOwner();
|
||||
|
||||
if (pSprite->statnum == kStatExplosion) return;
|
||||
sfxKill3DSound(pSprite, -1, -1);
|
||||
evKill(pSprite->index, 3);
|
||||
|
||||
int nType = kExplosionStandard;
|
||||
|
||||
switch (pSprite->type)
|
||||
{
|
||||
case kMissileFireballNapalm:
|
||||
nType = kExplosionNapalm;
|
||||
seqSpawn(4, 3, nXSprite, -1);
|
||||
if (Chance(0x8000))
|
||||
pSprite->cstat |= 4;
|
||||
seqSpawn(4, actor, -1);
|
||||
if (Chance(0x8000)) pSprite->cstat |= 4;
|
||||
sfxPlay3DSound(pSprite, 303, -1, 0);
|
||||
GibSprite(pSprite, GIBTYPE_5, NULL, NULL);
|
||||
GibSprite(pSprite, GIBTYPE_5, nullptr, nullptr);
|
||||
break;
|
||||
|
||||
case kMissileFlareAlt:
|
||||
nType = kExplosionFireball;
|
||||
seqSpawn(9, 3, nXSprite, -1);
|
||||
if (Chance(0x8000))
|
||||
pSprite->cstat |= 4;
|
||||
sfxPlay3DSound(pSprite, 306, 24+(pSprite->index&3), 1);
|
||||
GibSprite(pSprite, GIBTYPE_5, NULL, NULL);
|
||||
seqSpawn(9, actor, -1);
|
||||
if (Chance(0x8000)) pSprite->cstat |= 4;
|
||||
sfxPlay3DSound(pSprite, 306, 24 + (pSprite->index & 3), FX_GlobalChannel); // ouch...
|
||||
GibSprite(pSprite, GIBTYPE_5, nullptr, nullptr);
|
||||
break;
|
||||
|
||||
case kMissileFireballCerberus:
|
||||
case kMissileFireballTchernobog:
|
||||
nType = kExplosionFireball;
|
||||
seqSpawn(5, 3, nXSprite, -1);
|
||||
seqSpawn(5, actor, -1);
|
||||
sfxPlay3DSound(pSprite, 304, -1, 0);
|
||||
GibSprite(pSprite, GIBTYPE_5, NULL, NULL);
|
||||
GibSprite(pSprite, GIBTYPE_5, nullptr, nullptr);
|
||||
break;
|
||||
|
||||
case kThingArmedTNTStick:
|
||||
nType = kExplosionSmall;
|
||||
if (gSpriteHit[nXSprite].florhit == 0) seqSpawn(4,3,nXSprite,-1);
|
||||
else seqSpawn(3,3,nXSprite,-1);
|
||||
if (actor->hit().florhit == 0) seqSpawn(4, actor, -1);
|
||||
else seqSpawn(3, actor, -1);
|
||||
sfxPlay3DSound(pSprite, 303, -1, 0);
|
||||
GibSprite(pSprite, GIBTYPE_5, NULL, NULL);
|
||||
GibSprite(pSprite, GIBTYPE_5, nullptr, nullptr);
|
||||
break;
|
||||
|
||||
case kThingArmedProxBomb:
|
||||
case kThingArmedRemoteBomb:
|
||||
case kThingArmedTNTBundle:
|
||||
#ifdef NOONE_EXTENSIONS
|
||||
#ifdef NOONE_EXTENSIONS
|
||||
case kModernThingTNTProx:
|
||||
#endif
|
||||
#endif
|
||||
nType = kExplosionStandard;
|
||||
if (gSpriteHit[nXSprite].florhit == 0)
|
||||
seqSpawn(4,3,nXSprite,-1);
|
||||
if (actor->hit().florhit == 0) seqSpawn(4, actor, -1);
|
||||
else
|
||||
seqSpawn(3,3,nXSprite,-1);
|
||||
seqSpawn(3, actor, -1);
|
||||
sfxPlay3DSound(pSprite, 304, -1, 0);
|
||||
GibSprite(pSprite, GIBTYPE_5, NULL, NULL);
|
||||
GibSprite(pSprite, GIBTYPE_5, nullptr, nullptr);
|
||||
break;
|
||||
|
||||
case kThingArmedSpray:
|
||||
nType = kExplosionSpray;
|
||||
seqSpawn(5, 3, nXSprite, -1);
|
||||
seqSpawn(5, actor, -1);
|
||||
sfxPlay3DSound(pSprite, 307, -1, 0);
|
||||
GibSprite(pSprite, GIBTYPE_5, NULL, NULL);
|
||||
GibSprite(pSprite, GIBTYPE_5, nullptr, nullptr);
|
||||
break;
|
||||
|
||||
case kThingTNTBarrel:
|
||||
{
|
||||
spritetype *pSprite2 = actSpawnSprite_(pSprite->sectnum, pSprite->x, pSprite->y, pSprite->z, 0, 1);
|
||||
pSprite2->owner = pSprite->owner;
|
||||
auto spawned = actSpawnSprite(pSprite->sectnum, pSprite->x, pSprite->y, pSprite->z, 0, 1);
|
||||
spawned->SetOwner(actor->GetOwner());
|
||||
if (actCheckRespawn(pSprite))
|
||||
{
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
pXSprite->state = 1;
|
||||
pXSprite->health = thingInfo[0].startHealth<<4;
|
||||
pXSprite->health = thingInfo[0].startHealth << 4;
|
||||
}
|
||||
else
|
||||
actPostSprite(pSprite->index, kStatFree);
|
||||
else actPostSprite(actor, kStatFree);
|
||||
|
||||
nType = kExplosionLarge;
|
||||
nXSprite = pSprite2->extra;
|
||||
seqSpawn(4, 3, nXSprite, -1);
|
||||
sfxPlay3DSound(pSprite2, 305, -1, 0);
|
||||
GibSprite(pSprite2, GIBTYPE_14, NULL, NULL);
|
||||
pSprite = pSprite2;
|
||||
seqSpawn(4, spawned, -1);
|
||||
actor = spawned;
|
||||
pSprite = &spawned->s();
|
||||
pXSprite = &spawned->x();
|
||||
|
||||
sfxPlay3DSound(pSprite, 305, -1, 0);
|
||||
GibSprite(pSprite, GIBTYPE_14, nullptr, nullptr);
|
||||
break;
|
||||
}
|
||||
case kTrapExploder:
|
||||
case kTrapExploder:
|
||||
{
|
||||
// Defaults for exploder
|
||||
nType = 1; int nSnd = 304; int nSeq = 4;
|
||||
nType = 1;
|
||||
int nSnd = 304;
|
||||
int nSeq = 4;
|
||||
|
||||
#ifdef NOONE_EXTENSIONS
|
||||
#ifdef NOONE_EXTENSIONS
|
||||
// allow to customize hidden exploder trap
|
||||
if (gModernMap) {
|
||||
// Temp variables for override via data fields
|
||||
int tSnd = 0; int tSeq = 0;
|
||||
|
||||
|
||||
XSPRITE* pXSPrite = &xsprite[nXSprite];
|
||||
nType = pXSPrite->data1; // Explosion type
|
||||
tSeq = pXSPrite->data2; // SEQ id
|
||||
tSnd = pXSPrite->data3; // Sound Id
|
||||
if (gModernMap)
|
||||
{
|
||||
nType = pXSprite->data1; // Explosion type
|
||||
int tSeq = pXSprite->data2; // SEQ id
|
||||
int tSnd = pXSprite->data3; // Sound Id
|
||||
|
||||
if (nType <= 1 || nType > kExplodeMax) { nType = 1; nSeq = 4; nSnd = 304; }
|
||||
else if (nType == 2) { nSeq = 4; nSnd = 305; }
|
||||
|
@ -5618,77 +5611,73 @@ void actExplodeSprite(spritetype *pSprite)
|
|||
if (tSeq > 0) nSeq = tSeq;
|
||||
if (tSnd > 0) nSnd = tSnd;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (getSequence(nSeq))
|
||||
seqSpawn(nSeq, 3, nXSprite, -1);
|
||||
#endif
|
||||
|
||||
if (getSequence(nSeq)) seqSpawn(nSeq, actor, -1);
|
||||
sfxPlay3DSound(pSprite, nSnd, -1, 0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case kThingPodFireBall:
|
||||
nType = kExplosionFireball;
|
||||
seqSpawn(9, 3, nXSprite, -1);
|
||||
seqSpawn(9, actor, -1);
|
||||
sfxPlay3DSound(pSprite, 307, -1, 0);
|
||||
GibSprite(pSprite, GIBTYPE_5, NULL, NULL);
|
||||
GibSprite(pSprite, GIBTYPE_5, nullptr, nullptr);
|
||||
sub_746D4(pSprite, 240);
|
||||
break;
|
||||
|
||||
default:
|
||||
nType = kExplosionStandard;
|
||||
seqSpawn(4, 3, nXSprite, -1);
|
||||
if (Chance(0x8000))
|
||||
pSprite->cstat |= 4;
|
||||
seqSpawn(4, actor, -1);
|
||||
if (Chance(0x8000)) pSprite->cstat |= 4;
|
||||
sfxPlay3DSound(pSprite, 303, -1, 0);
|
||||
GibSprite(pSprite, GIBTYPE_5, NULL, NULL);
|
||||
GibSprite(pSprite, GIBTYPE_5, nullptr, nullptr);
|
||||
break;
|
||||
}
|
||||
int nSprite = pSprite->index;
|
||||
xvel[nSprite] = yvel[nSprite] = zvel[nSprite] = 0;
|
||||
actPostSprite(nSprite, kStatExplosion);
|
||||
actor->xvel() = actor->yvel() = actor->zvel() = 0;
|
||||
actPostSprite(actor, kStatExplosion);
|
||||
pSprite->xrepeat = pSprite->yrepeat = explodeInfo[nType].repeat;
|
||||
|
||||
pSprite->flags &= ~3;
|
||||
pSprite->type = nType;
|
||||
const EXPLOSION *pExplodeInfo = &explodeInfo[nType];
|
||||
xsprite[nXSprite].target = 0;
|
||||
xsprite[nXSprite].data1 = pExplodeInfo->ticks;
|
||||
xsprite[nXSprite].data2 = pExplodeInfo->quakeEffect;
|
||||
xsprite[nXSprite].data3 = pExplodeInfo->flashEffect;
|
||||
const EXPLOSION* pExplodeInfo = &explodeInfo[nType];
|
||||
pXSprite->target = 0;
|
||||
pXSprite->data1 = pExplodeInfo->ticks;
|
||||
pXSprite->data2 = pExplodeInfo->quakeEffect;
|
||||
pXSprite->data3 = pExplodeInfo->flashEffect;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void actActivateGibObject(DBloodActor* actor)
|
||||
{
|
||||
auto pXSprite = &actor->x();
|
||||
auto pSprite = &actor->s();
|
||||
int vdx = ClipRange(pXSprite->data1, 0, 31);
|
||||
int vc = ClipRange(pXSprite->data2, 0, 31);
|
||||
int v4 = ClipRange(pXSprite->data3, 0, 31);
|
||||
int vbp = pXSprite->data4;
|
||||
int v8 = pXSprite->dropMsg;
|
||||
if (vdx > 0)
|
||||
GibSprite(pSprite, (GIBTYPE)(vdx-1), NULL, NULL);
|
||||
if (vc > 0)
|
||||
GibSprite(pSprite, (GIBTYPE)(vc-1), NULL, NULL);
|
||||
if (v4 > 0 && pXSprite->burnTime > 0)
|
||||
GibSprite(pSprite, (GIBTYPE)(v4-1), NULL, NULL);
|
||||
if (vbp > 0)
|
||||
sfxPlay3DSound(pSprite->x, pSprite->y, pSprite->z, vbp, pSprite->sectnum);
|
||||
if (v8 > 0)
|
||||
actDropObject(pSprite, v8);
|
||||
|
||||
if (!(pSprite->cstat&32768) && !(pSprite->flags&kHitagRespawn))
|
||||
actPostSprite(pSprite->index, kStatFree);
|
||||
int gib1 = ClipRange(pXSprite->data1, 0, 31);
|
||||
int gib2 = ClipRange(pXSprite->data2, 0, 31);
|
||||
int gib3 = ClipRange(pXSprite->data3, 0, 31);
|
||||
int sound = pXSprite->data4;
|
||||
int dropmsg = pXSprite->dropMsg;
|
||||
|
||||
if (gib1 > 0) GibSprite(pSprite, (GIBTYPE)(gib1 - 1), nullptr, nullptr);
|
||||
if (gib2 > 0) GibSprite(pSprite, (GIBTYPE)(gib2 - 1), nullptr, nullptr);
|
||||
if (gib3 > 0 && pXSprite->burnTime > 0) GibSprite(pSprite, (GIBTYPE)(gib3 - 1), nullptr, nullptr);
|
||||
if (sound > 0) sfxPlay3DSound(pSprite->x, pSprite->y, pSprite->z, sound, pSprite->sectnum);
|
||||
if (dropmsg > 0) actDropObject(pSprite, dropmsg);
|
||||
|
||||
if (!(pSprite->cstat & 32768) && !(pSprite->flags & kHitagRespawn))
|
||||
actPostSprite(actor, kStatFree);
|
||||
}
|
||||
|
||||
bool IsUnderWater(spritetype *pSprite)
|
||||
{
|
||||
int nSector = pSprite->sectnum;
|
||||
int nXSector = sector[nSector].extra;
|
||||
if (nXSector > 0 && nXSector < kMaxXSectors)
|
||||
if (xsector[nXSector].Underwater)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void MakeSplash(DBloodActor *actor);
|
||||
|
||||
|
@ -5922,7 +5911,7 @@ void actProcessSprites(void)
|
|||
if ((hit&0xc000) != 0xc000 && (nObject < 0 || nObject >= 4096))
|
||||
break;
|
||||
assert(nObject >= 0 && nObject < kMaxSprites);
|
||||
actExplodeSprite(pSprite);
|
||||
actExplodeSprite(&bloodActors[pSprite->index]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -5939,7 +5928,7 @@ void actProcessSprites(void)
|
|||
if (pSprite->flags & 32)
|
||||
continue;
|
||||
viewBackupSpriteLoc(nSprite, pSprite);
|
||||
int hit = MoveMissile(pSprite);
|
||||
int hit = MoveMissile(&bloodActors[nSprite]);
|
||||
if (hit >= 0)
|
||||
actImpactMissile(&bloodActors[pSprite->index], hit);
|
||||
}
|
||||
|
|
|
@ -229,12 +229,8 @@ int actDamageSprite(int nSource, spritetype *pSprite, DAMAGE_TYPE a3, int a4);
|
|||
int actDamageSprite(DBloodActor* pSource, DBloodActor* pTarget, DAMAGE_TYPE damageType, int damage);
|
||||
void actHitcodeToData(int a1, HITINFO *pHitInfo, DBloodActor **actor, walltype **a7 = nullptr);
|
||||
void actAirDrag(DBloodActor *pSprite, int a2);
|
||||
int MoveThing(spritetype *pSprite);
|
||||
void MoveDude(spritetype *pSprite);
|
||||
int MoveMissile(spritetype *pSprite);
|
||||
void actExplodeSprite(spritetype *pSprite);
|
||||
void actExplodeSprite(DBloodActor *pSprite);
|
||||
void actActivateGibObject(DBloodActor *actor);
|
||||
bool IsUnderWater(spritetype *pSprite);
|
||||
void actProcessSprites(void);
|
||||
spritetype * actSpawnSprite_(int nSector, int x, int y, int z, int nStat, char a6);
|
||||
DBloodActor* actSpawnSprite(int nSector, int x, int y, int z, int nStat, bool a6);
|
||||
|
|
|
@ -5042,7 +5042,7 @@ bool modernTypeOperateSprite(int nSprite, spritetype* pSprite, XSPRITE* pXSprite
|
|||
pXSprite->Proximity = 1;
|
||||
break;
|
||||
default:
|
||||
actExplodeSprite(pSprite);
|
||||
actExplodeSprite(&bloodActors[pSprite->index]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -169,14 +169,7 @@ void sfxPlay3DSound(int x, int y, int z, int soundId, int nSector)
|
|||
if (chan) chan->UserData = nSector;
|
||||
}
|
||||
|
||||
enum EPlayFlags
|
||||
{
|
||||
FX_GlobalChannel = 1,
|
||||
FX_SoundMatch = 2,
|
||||
FX_ChannelMatch = 4,
|
||||
};
|
||||
|
||||
void sfxPlay3DSoundCP(spritetype* pSprite, int soundId, int a3, int a4, int pitch, int volume)
|
||||
void sfxPlay3DSoundCP(spritetype* pSprite, int soundId, int playchannel, int playflags, int pitch, int volume)
|
||||
{
|
||||
if (!SoundEnabled() || soundId < 0 || !pSprite) return;
|
||||
auto sid = soundEngine->FindSoundByResID(soundId);
|
||||
|
@ -188,17 +181,17 @@ void sfxPlay3DSoundCP(spritetype* pSprite, int soundId, int a3, int a4, int pitc
|
|||
sid = getSfx(sid, attenuation, pitch, volume);
|
||||
if (volume == -1) volume = 80;
|
||||
|
||||
if (a3 >= 0)
|
||||
if (playchannel >= 0)
|
||||
{
|
||||
a3++; // This is to make 0 a valid channel value.
|
||||
playchannel++; // This is to make 0 a valid channel value.
|
||||
if (soundEngine->EnumerateChannels([=](FSoundChan* chan) -> int
|
||||
{
|
||||
if (chan->SourceType != SOURCE_Actor) return false; // other source types are not our business.
|
||||
if (chan->EntChannel == a3 && (chan->Source == pSprite || (a4 & FX_GlobalChannel) != 0))
|
||||
if (chan->EntChannel == playchannel && (chan->Source == pSprite || (playflags & FX_GlobalChannel) != 0))
|
||||
{
|
||||
if ((a4 & FX_ChannelMatch) != 0 && chan->EntChannel == a3)
|
||||
if ((playflags & FX_ChannelMatch) != 0 && chan->EntChannel == playchannel)
|
||||
return true;
|
||||
if ((a4 & FX_SoundMatch) != 0 && chan->OrgID == sid)
|
||||
if ((playflags & FX_SoundMatch) != 0 && chan->OrgID == sid)
|
||||
return true;
|
||||
soundEngine->StopChannel(chan);
|
||||
return -1;
|
||||
|
@ -209,10 +202,10 @@ void sfxPlay3DSoundCP(spritetype* pSprite, int soundId, int a3, int a4, int pitc
|
|||
}
|
||||
|
||||
auto sfx = soundEngine->GetSfx(sid);
|
||||
EChanFlags flags = a3 == -1 ? CHANF_OVERLAP : CHANF_NONE;
|
||||
EChanFlags flags = playchannel == -1 ? CHANF_OVERLAP : CHANF_NONE;
|
||||
if (sfx && sfx->LoopStart >= 0) flags |= CHANF_LOOP;
|
||||
|
||||
soundEngine->StartSound(SOURCE_Actor, pSprite, &svec, a3, flags, sid, volume * (0.8f / 80.f), attenuation, nullptr, pitch / 65536.f);
|
||||
soundEngine->StartSound(SOURCE_Actor, pSprite, &svec, playchannel, flags, sid, volume * (0.8f / 80.f), attenuation, nullptr, pitch / 65536.f);
|
||||
}
|
||||
|
||||
void sfxPlay3DSound(spritetype* pSprite, int soundId, int a3, int a4)
|
||||
|
|
|
@ -62,4 +62,12 @@ void ambProcess(void);
|
|||
void ambKillAll(void);
|
||||
void ambInit(void);
|
||||
|
||||
enum EPlayFlags
|
||||
{
|
||||
FX_GlobalChannel = 1,
|
||||
FX_SoundMatch = 2,
|
||||
FX_ChannelMatch = 4,
|
||||
};
|
||||
|
||||
|
||||
END_BLD_NS
|
||||
|
|
|
@ -495,7 +495,7 @@ void OperateSprite(int nSprite, XSPRITE *pXSprite, EVENT event)
|
|||
case kThingArmedTNTStick:
|
||||
case kThingArmedTNTBundle:
|
||||
case kThingArmedSpray:
|
||||
actExplodeSprite(pSprite);
|
||||
actExplodeSprite(&bloodActors[pSprite->index]);
|
||||
break;
|
||||
case kTrapExploder:
|
||||
switch (event.cmd) {
|
||||
|
@ -504,13 +504,13 @@ void OperateSprite(int nSprite, XSPRITE *pXSprite, EVENT event)
|
|||
break;
|
||||
default:
|
||||
pSprite->cstat &= (unsigned short)~CSTAT_SPRITE_INVISIBLE;
|
||||
actExplodeSprite(pSprite);
|
||||
actExplodeSprite(&bloodActors[pSprite->index]);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case kThingArmedRemoteBomb:
|
||||
if (pSprite->statnum != kStatRespawn) {
|
||||
if (event.cmd != kCmdOn) actExplodeSprite(pSprite);
|
||||
if (event.cmd != kCmdOn) actExplodeSprite(&bloodActors[pSprite->index]);
|
||||
else {
|
||||
sfxPlay3DSound(pSprite, 454, 0, 0);
|
||||
evPost(nSprite, 3, 18, kCmdOff);
|
||||
|
@ -531,7 +531,7 @@ void OperateSprite(int nSprite, XSPRITE *pXSprite, EVENT event)
|
|||
pXSprite->Proximity = 1;
|
||||
break;
|
||||
default:
|
||||
actExplodeSprite(pSprite);
|
||||
actExplodeSprite(&bloodActors[pSprite->index]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue