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