|
|
|
@ -2742,7 +2742,7 @@ static void actNapalmMove(DBloodActor* actor)
|
|
|
|
|
|
|
|
|
|
if (pXSprite->data4 > 1)
|
|
|
|
|
{
|
|
|
|
|
GibSprite(pSprite, GIBTYPE_5, NULL, NULL);
|
|
|
|
|
GibSprite(pSprite, GIBTYPE_5, nullptr, nullptr);
|
|
|
|
|
int spawnparam[2];
|
|
|
|
|
spawnparam[0] = pXSprite->data4 >> 1;
|
|
|
|
|
spawnparam[1] = pXSprite->data4 - spawnparam[0];
|
|
|
|
@ -2880,7 +2880,7 @@ static DBloodActor* actDropFlag(DBloodActor* actor, int nType)
|
|
|
|
|
auto act2 = actDropItem(actor, nType);
|
|
|
|
|
if (act2 && gGameOptions.nGameType == 3)
|
|
|
|
|
{
|
|
|
|
|
evPost(act2->s().index, 3, 1800, kCallbackReturnFlag);
|
|
|
|
|
evPost(act2, 1800, kCallbackReturnFlag);
|
|
|
|
|
}
|
|
|
|
|
return act2;
|
|
|
|
|
}
|
|
|
|
@ -2949,7 +2949,7 @@ static bool actKillModernDude(DBloodActor* actor, DAMAGE_TYPE damageType)
|
|
|
|
|
auto pXSprite = &actor->x();
|
|
|
|
|
GENDUDEEXTRA* pExtra = genDudeExtra(pSprite);
|
|
|
|
|
removeDudeStuff(pSprite);
|
|
|
|
|
if (pXSprite->txID <= 0 || getNextIncarnation(pXSprite) == NULL)
|
|
|
|
|
if (pXSprite->txID <= 0 || getNextIncarnation(pXSprite) == nullptr)
|
|
|
|
|
{
|
|
|
|
|
if (pExtra->weaponType == kGenDudeWeaponKamikaze && Chance(0x4000) && damageType != DAMAGE_TYPE_5 && damageType != DAMAGE_TYPE_4)
|
|
|
|
|
{
|
|
|
|
@ -3280,7 +3280,7 @@ static void zombieAxeNormalDeath(DBloodActor* actor, int nSeq)
|
|
|
|
|
else if (nSeq == 1 && Chance(0x4000))
|
|
|
|
|
{
|
|
|
|
|
seqSpawn(dudeInfo[nType].seqStartID + 7, actor, nDudeToGibClient1);
|
|
|
|
|
evPost(pSprite->index, 3, 0, kCallbackFXZombieSpurt);
|
|
|
|
|
evPost(actor, 0, kCallbackFXZombieSpurt);
|
|
|
|
|
sfxPlay3DSound(pSprite, 362, -1, 0);
|
|
|
|
|
actor->x().data1 = 35;
|
|
|
|
|
actor->x().data2 = 5;
|
|
|
|
@ -3308,7 +3308,7 @@ static void burningCultistDeath(DBloodActor* actor, int nSeq)
|
|
|
|
|
if (Chance(0x8000))
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < 3; i++)
|
|
|
|
|
GibSprite(pSprite, GIBTYPE_7, NULL, NULL);
|
|
|
|
|
GibSprite(pSprite, GIBTYPE_7, nullptr, nullptr);
|
|
|
|
|
seqSpawn(dudeInfo[nType].seqStartID + 16 - Random(1), actor, nDudeToGibClient1);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
@ -3454,7 +3454,7 @@ void actKillDude(DBloodActor* killerActor, DBloodActor* actor, DAMAGE_TYPE damag
|
|
|
|
|
gPlayer[p].setFragger(nullptr);
|
|
|
|
|
}
|
|
|
|
|
if (pSprite->type != kDudeCultistBeast)
|
|
|
|
|
trTriggerSprite(pSprite->index, pXSprite, kCmdOff);
|
|
|
|
|
trTriggerSprite(actor, kCmdOff);
|
|
|
|
|
|
|
|
|
|
pSprite->flags |= 7;
|
|
|
|
|
checkAddFrag(killerActor, actor);
|
|
|
|
@ -3735,7 +3735,7 @@ static int actDamageThing(DBloodActor* source, DBloodActor* actor, int damage, D
|
|
|
|
|
#ifdef NOONE_EXTENSIONS
|
|
|
|
|
case kModernThingEnemyLifeLeech:
|
|
|
|
|
#endif
|
|
|
|
|
GibSprite(pSprite, GIBTYPE_14, NULL, NULL);
|
|
|
|
|
GibSprite(pSprite, GIBTYPE_14, nullptr, nullptr);
|
|
|
|
|
pXSprite->data1 = pXSprite->data2 = pXSprite->data3 = pXSprite->DudeLockout = 0;
|
|
|
|
|
pXSprite->stateTimer = pXSprite->data4 = pXSprite->isTriggered = 0;
|
|
|
|
|
|
|
|
|
@ -3751,7 +3751,7 @@ static int actDamageThing(DBloodActor* source, DBloodActor* actor, int damage, D
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
trTriggerSprite(pSprite->index, pXSprite, kCmdOff);
|
|
|
|
|
trTriggerSprite(actor, kCmdOff);
|
|
|
|
|
|
|
|
|
|
switch (pSprite->type)
|
|
|
|
|
{
|
|
|
|
@ -3772,7 +3772,7 @@ static int actDamageThing(DBloodActor* source, DBloodActor* actor, int damage, D
|
|
|
|
|
|
|
|
|
|
case kThingFluorescent:
|
|
|
|
|
seqSpawn(12, 3, pSprite->extra, -1);
|
|
|
|
|
GibSprite(pSprite, GIBTYPE_6, NULL, NULL);
|
|
|
|
|
GibSprite(pSprite, GIBTYPE_6, nullptr, nullptr);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case kThingSpiderWeb:
|
|
|
|
@ -3781,14 +3781,14 @@ static int actDamageThing(DBloodActor* source, DBloodActor* actor, int damage, D
|
|
|
|
|
|
|
|
|
|
case kThingMetalGrate:
|
|
|
|
|
seqSpawn(21, 3, pSprite->extra, -1);
|
|
|
|
|
GibSprite(pSprite, GIBTYPE_4, NULL, NULL);
|
|
|
|
|
GibSprite(pSprite, GIBTYPE_4, nullptr, nullptr);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case kThingFlammableTree:
|
|
|
|
|
switch (pXSprite->data1)
|
|
|
|
|
{
|
|
|
|
|
case -1:
|
|
|
|
|
GibSprite(pSprite, GIBTYPE_14, NULL, NULL);
|
|
|
|
|
GibSprite(pSprite, GIBTYPE_14, nullptr, nullptr);
|
|
|
|
|
sfxPlay3DSound(pSprite->x, pSprite->y, pSprite->z, 312, pSprite->sectnum);
|
|
|
|
|
actPostSprite(actor, kStatFree);
|
|
|
|
|
break;
|
|
|
|
@ -3828,7 +3828,7 @@ int actDamageSprite(DBloodActor* source, DBloodActor* actor, DAMAGE_TYPE damageT
|
|
|
|
|
|
|
|
|
|
if (source == nullptr) source = actor;
|
|
|
|
|
|
|
|
|
|
PLAYER* pSourcePlayer = NULL;
|
|
|
|
|
PLAYER* pSourcePlayer = nullptr;
|
|
|
|
|
if (source->IsPlayerActor()) pSourcePlayer = &gPlayer[source->s().type - kDudePlayer1];
|
|
|
|
|
if (!gGameOptions.bFriendlyFire && IsTargetTeammate(pSourcePlayer, pSprite)) return 0;
|
|
|
|
|
|
|
|
|
@ -3845,364 +3845,322 @@ int actDamageSprite(DBloodActor* source, DBloodActor* actor, DAMAGE_TYPE damageT
|
|
|
|
|
return damage >> 4;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// this was condensed to the parts actually in use.
|
|
|
|
|
//
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
void actHitcodeToData(int a1, HITINFO* pHitInfo, DBloodActor** pActor, walltype** a7)
|
|
|
|
|
{
|
|
|
|
|
assert(pHitInfo != nullptr);
|
|
|
|
|
int nSprite = -1;
|
|
|
|
|
int nWall = -1;
|
|
|
|
|
walltype* pWall = nullptr;
|
|
|
|
|
switch (a1)
|
|
|
|
|
{
|
|
|
|
|
case 3:
|
|
|
|
|
case 5:
|
|
|
|
|
nSprite = pHitInfo->hitsprite;
|
|
|
|
|
break;
|
|
|
|
|
case 0:
|
|
|
|
|
case 4:
|
|
|
|
|
nWall = pHitInfo->hitwall;
|
|
|
|
|
if (nWall >= 0 && nWall < kMaxWalls) pWall = &wall[nWall];
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (pActor) *pActor = nSprite == -1 ? nullptr : &bloodActors[nSprite];
|
|
|
|
|
if (a7) *a7 = pWall;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
void actHitcodeToData(int a1, HITINFO *pHitInfo, int *a3, spritetype **a4, XSPRITE **a5, int *a6, walltype **a7, XWALL **a8, int *a9, sectortype **a10, XSECTOR **a11)
|
|
|
|
|
static void actImpactMissile(DBloodActor* missileActor, int hitCode)
|
|
|
|
|
{
|
|
|
|
|
assert(pHitInfo != NULL);
|
|
|
|
|
int nSprite = -1;
|
|
|
|
|
spritetype *pSprite = NULL;
|
|
|
|
|
XSPRITE *pXSprite = NULL;
|
|
|
|
|
int nWall = -1;
|
|
|
|
|
walltype *pWall = NULL;
|
|
|
|
|
XWALL *pXWall = NULL;
|
|
|
|
|
int nSector = -1;
|
|
|
|
|
sectortype *pSector = NULL;
|
|
|
|
|
XSECTOR *pXSector = NULL;
|
|
|
|
|
switch (a1)
|
|
|
|
|
{
|
|
|
|
|
case 3:
|
|
|
|
|
case 5:
|
|
|
|
|
nSprite = pHitInfo->hitsprite;
|
|
|
|
|
assert(nSprite >= 0 && nSprite < kMaxSprites);
|
|
|
|
|
pSprite = &sprite[nSprite];
|
|
|
|
|
if (pSprite->extra > 0)
|
|
|
|
|
pXSprite = &xsprite[pSprite->extra];
|
|
|
|
|
break;
|
|
|
|
|
case 0:
|
|
|
|
|
case 4:
|
|
|
|
|
nWall = pHitInfo->hitwall;
|
|
|
|
|
assert(nWall >= 0 && nWall < kMaxWalls);
|
|
|
|
|
pWall = &wall[nWall];
|
|
|
|
|
if (pWall->extra > 0)
|
|
|
|
|
pXWall = &xwall[pWall->extra];
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
|
|
|
|
case 2:
|
|
|
|
|
case 6:
|
|
|
|
|
nSector = pHitInfo->hitsect;
|
|
|
|
|
assert(nSector >= 0 && nSector < kMaxSectors);
|
|
|
|
|
pSector = §or[nSector];
|
|
|
|
|
if (pSector->extra > 0)
|
|
|
|
|
pXSector = &xsector[pSector->extra];
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (a3)
|
|
|
|
|
*a3 = nSprite;
|
|
|
|
|
if (a4)
|
|
|
|
|
*a4 = pSprite;
|
|
|
|
|
if (a5)
|
|
|
|
|
*a5 = pXSprite;
|
|
|
|
|
if (a6)
|
|
|
|
|
*a6 = nWall;
|
|
|
|
|
if (a7)
|
|
|
|
|
*a7 = pWall;
|
|
|
|
|
if (a8)
|
|
|
|
|
*a8 = pXWall;
|
|
|
|
|
if (a9)
|
|
|
|
|
*a9 = nSector;
|
|
|
|
|
if (a10)
|
|
|
|
|
*a10 = pSector;
|
|
|
|
|
if (a11)
|
|
|
|
|
*a11 = pXSector;
|
|
|
|
|
}
|
|
|
|
|
auto pMissile = &missileActor->s();
|
|
|
|
|
XSPRITE* pXMissile = &missileActor->x();
|
|
|
|
|
auto missileOwner = missileActor->GetOwner();
|
|
|
|
|
|
|
|
|
|
void actImpactMissile(spritetype *pMissile, int hitCode)
|
|
|
|
|
{
|
|
|
|
|
int nXMissile = pMissile->extra;
|
|
|
|
|
assert(nXMissile > 0 && nXMissile < kMaxXSprites);
|
|
|
|
|
XSPRITE *pXMissile = &xsprite[pMissile->extra];
|
|
|
|
|
|
|
|
|
|
int nSpriteHit = -1; int nWallHit = -1; int nSectorHit = -1;
|
|
|
|
|
spritetype *pSpriteHit = NULL; XSPRITE *pXSpriteHit = NULL;
|
|
|
|
|
walltype *pWallHit = NULL; XWALL *pXWallHit = NULL;
|
|
|
|
|
sectortype *pSectorHit = NULL; XSECTOR *pXSectorHit = NULL;
|
|
|
|
|
DBloodActor* actorHit = nullptr;
|
|
|
|
|
walltype* pWallHit = nullptr;
|
|
|
|
|
|
|
|
|
|
actHitcodeToData(hitCode, &gHitInfo, &nSpriteHit, &pSpriteHit, &pXSpriteHit, &nWallHit, &pWallHit, &pXWallHit, &nSectorHit, &pSectorHit, &pXSectorHit);
|
|
|
|
|
const THINGINFO *pThingInfo = NULL; DUDEINFO *pDudeInfo = NULL;
|
|
|
|
|
actHitcodeToData(hitCode, &gHitInfo, &actorHit, &pWallHit);
|
|
|
|
|
spritetype* pSpriteHit = actorHit ? &actorHit->s() : nullptr;
|
|
|
|
|
XSPRITE* pXSpriteHit = actorHit && actorHit->hasX() ? &actorHit->x() : nullptr;
|
|
|
|
|
|
|
|
|
|
if (hitCode == 3 && pSpriteHit) {
|
|
|
|
|
switch (pSpriteHit->statnum) {
|
|
|
|
|
case kStatThing:
|
|
|
|
|
pThingInfo = &thingInfo[pSpriteHit->type - kThingBase];
|
|
|
|
|
break;
|
|
|
|
|
case kStatDude:
|
|
|
|
|
pDudeInfo = getDudeInfo(pSpriteHit->type);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
switch (pMissile->type) {
|
|
|
|
|
case kMissileLifeLeechRegular:
|
|
|
|
|
if (hitCode == 3 && pSpriteHit && (pThingInfo || pDudeInfo)) {
|
|
|
|
|
int nOwner = pMissile->owner;
|
|
|
|
|
DAMAGE_TYPE rand1 = (DAMAGE_TYPE)Random(7);
|
|
|
|
|
int rand2 = (7 + Random(7)) << 4;
|
|
|
|
|
int nDamage = actDamageSprite(nOwner, pSpriteHit, rand1, rand2);
|
|
|
|
|
if ((pThingInfo && pThingInfo->dmgControl[DAMAGE_TYPE_1] != 0) || (pDudeInfo && pDudeInfo->damageVal[DAMAGE_TYPE_1] != 0))
|
|
|
|
|
actBurnSprite(pMissile->owner, pXSpriteHit, 360);
|
|
|
|
|
const THINGINFO* pThingInfo = nullptr;
|
|
|
|
|
DUDEINFO* pDudeInfo = nullptr;
|
|
|
|
|
|
|
|
|
|
// by NoOne: make Life Leech heal user, just like it was in 1.0x versions
|
|
|
|
|
if (gGameOptions.weaponsV10x && !VanillaMode() && !DemoRecordStatus() && pDudeInfo != NULL) {
|
|
|
|
|
spritetype* pSource = &sprite[nOwner];
|
|
|
|
|
XSPRITE* pXSource = (pSource->extra >= 0) ? &xsprite[pSource->extra] : NULL;
|
|
|
|
|
if (hitCode == 3 && pSpriteHit)
|
|
|
|
|
{
|
|
|
|
|
switch (pSpriteHit->statnum)
|
|
|
|
|
{
|
|
|
|
|
case kStatThing:
|
|
|
|
|
pThingInfo = &thingInfo[pSpriteHit->type - kThingBase];
|
|
|
|
|
break;
|
|
|
|
|
case kStatDude:
|
|
|
|
|
pDudeInfo = getDudeInfo(pSpriteHit->type);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
switch (pMissile->type)
|
|
|
|
|
{
|
|
|
|
|
case kMissileLifeLeechRegular:
|
|
|
|
|
if (hitCode == 3 && pSpriteHit && (pThingInfo || pDudeInfo))
|
|
|
|
|
{
|
|
|
|
|
DAMAGE_TYPE rand1 = (DAMAGE_TYPE)Random(7);
|
|
|
|
|
int rand2 = (7 + Random(7)) << 4;
|
|
|
|
|
int nDamage = actDamageSprite(missileOwner, actorHit, rand1, rand2);
|
|
|
|
|
|
|
|
|
|
if (IsDudeSprite(pSource) && pXSource != NULL && pXSource->health != 0)
|
|
|
|
|
if ((pThingInfo && pThingInfo->dmgControl[DAMAGE_TYPE_1] != 0) || (pDudeInfo && pDudeInfo->damageVal[DAMAGE_TYPE_1] != 0))
|
|
|
|
|
actBurnSprite(missileActor->GetOwner(), actorHit, 360);
|
|
|
|
|
|
|
|
|
|
actHealDude(pXSource, nDamage >> 2, getDudeInfo(pSource->type)->startHealth);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pMissile->extra > 0) {
|
|
|
|
|
actPostSprite(pMissile->index, kStatDecoration);
|
|
|
|
|
if (pMissile->ang == 1024) sfxPlay3DSound(pMissile, 307, -1, 0);
|
|
|
|
|
pMissile->type = kSpriteDecoration;
|
|
|
|
|
seqSpawn(9, 3, pMissile->extra, -1);
|
|
|
|
|
} else {
|
|
|
|
|
actPostSprite(pMissile->index, kStatFree);
|
|
|
|
|
}
|
|
|
|
|
// by NoOne: make Life Leech heal user, just like it was in 1.0x versions
|
|
|
|
|
if (gGameOptions.weaponsV10x && !VanillaMode() && !DemoRecordStatus() && pDudeInfo != nullptr)
|
|
|
|
|
{
|
|
|
|
|
if (missileOwner->IsDudeActor() && missileOwner->hasX() && missileOwner->x().health != 0)
|
|
|
|
|
actHealDude(missileOwner, nDamage >> 2, getDudeInfo(missileOwner->s().type)->startHealth);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
case kMissileTeslaAlt:
|
|
|
|
|
teslaHit(pMissile, hitCode);
|
|
|
|
|
switch (hitCode) {
|
|
|
|
|
case 0:
|
|
|
|
|
case 4:
|
|
|
|
|
if (pWallHit) {
|
|
|
|
|
spritetype* pFX = gFX.fxSpawn(FX_52, pMissile->sectnum, pMissile->x, pMissile->y, pMissile->z, 0);
|
|
|
|
|
if (pFX) pFX->ang = (GetWallAngle(nWallHit) + 512) & 2047;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
GibSprite(pMissile, GIBTYPE_24, NULL, NULL);
|
|
|
|
|
actPostSprite(pMissile->index, kStatFree);
|
|
|
|
|
break;
|
|
|
|
|
case kMissilePukeGreen:
|
|
|
|
|
seqKill(3, nXMissile);
|
|
|
|
|
if (hitCode == 3 && pSpriteHit && (pThingInfo || pDudeInfo))
|
|
|
|
|
{
|
|
|
|
|
int nOwner = pMissile->owner;
|
|
|
|
|
int nDamage = (15+Random(7))<<4;
|
|
|
|
|
actDamageSprite(nOwner, pSpriteHit, DAMAGE_TYPE_2, nDamage);
|
|
|
|
|
}
|
|
|
|
|
actPostSprite(pMissile->index, kStatFree);
|
|
|
|
|
break;
|
|
|
|
|
case kMissileArcGargoyle:
|
|
|
|
|
sfxKill3DSound(pMissile, -1, -1);
|
|
|
|
|
sfxPlay3DSound(pMissile->x, pMissile->y, pMissile->z, 306, pMissile->sectnum);
|
|
|
|
|
GibSprite(pMissile, GIBTYPE_6, NULL, NULL);
|
|
|
|
|
if (hitCode == 3 && pSpriteHit && (pThingInfo || pDudeInfo))
|
|
|
|
|
{
|
|
|
|
|
int nOwner = pMissile->owner;
|
|
|
|
|
int nDamage = (25+Random(20))<<4;
|
|
|
|
|
actDamageSprite(nOwner, pSpriteHit, DAMAGE_TYPE_5, nDamage);
|
|
|
|
|
}
|
|
|
|
|
actPostSprite(pMissile->index, kStatFree);
|
|
|
|
|
break;
|
|
|
|
|
case kMissileLifeLeechAltNormal:
|
|
|
|
|
case kMissileLifeLeechAltSmall:
|
|
|
|
|
sfxKill3DSound(pMissile, -1, -1);
|
|
|
|
|
sfxPlay3DSound(pMissile->x, pMissile->y, pMissile->z, 306, pMissile->sectnum);
|
|
|
|
|
if (hitCode == 3 && pSpriteHit && (pThingInfo || pDudeInfo)) {
|
|
|
|
|
int nOwner = pMissile->owner;
|
|
|
|
|
int nDmgMul = (pMissile->type == kMissileLifeLeechAltSmall) ? 6 : 3;
|
|
|
|
|
int nDamage = (nDmgMul+Random(nDmgMul))<<4;
|
|
|
|
|
actDamageSprite(nOwner, pSpriteHit, DAMAGE_TYPE_5, nDamage);
|
|
|
|
|
}
|
|
|
|
|
actPostSprite(pMissile->index, kStatFree);
|
|
|
|
|
break;
|
|
|
|
|
case kMissileFireball:
|
|
|
|
|
case kMissileFireballNapam:
|
|
|
|
|
if (hitCode == 3 && pSpriteHit && (pThingInfo || pDudeInfo))
|
|
|
|
|
{
|
|
|
|
|
if (pThingInfo && pSpriteHit->type == kThingTNTBarrel && pXSpriteHit->burnTime == 0)
|
|
|
|
|
evPost(nSpriteHit, 3, 0, kCallbackFXFlameLick);
|
|
|
|
|
int nOwner = pMissile->owner;
|
|
|
|
|
int nDamage = (50+Random(50))<<4;
|
|
|
|
|
actDamageSprite(nOwner, pSpriteHit, DAMAGE_TYPE_2, nDamage);
|
|
|
|
|
}
|
|
|
|
|
actExplodeSprite(pMissile);
|
|
|
|
|
break;
|
|
|
|
|
case kMissileFlareAlt:
|
|
|
|
|
sfxKill3DSound(pMissile, -1, -1);
|
|
|
|
|
actExplodeSprite(pMissile);
|
|
|
|
|
break;
|
|
|
|
|
case kMissileFlareRegular:
|
|
|
|
|
sfxKill3DSound(pMissile, -1, -1);
|
|
|
|
|
if ((hitCode == 3 && pSpriteHit) && (pThingInfo || pDudeInfo)) {
|
|
|
|
|
int nOwner = pMissile->owner;
|
|
|
|
|
if ((pThingInfo && pThingInfo->dmgControl[DAMAGE_TYPE_1] != 0) || (pDudeInfo && pDudeInfo->damageVal[DAMAGE_TYPE_1] != 0)) {
|
|
|
|
|
if (pThingInfo && pSpriteHit->type == kThingTNTBarrel && pXSpriteHit->burnTime == 0)
|
|
|
|
|
evPost(nSpriteHit, 3, 0, kCallbackFXFlameLick);
|
|
|
|
|
|
|
|
|
|
actBurnSprite(pMissile->owner, pXSpriteHit, 480);
|
|
|
|
|
actRadiusDamage(&bloodActors[nOwner], pMissile->x, pMissile->y, pMissile->z, pMissile->sectnum, 16, 20, 10, DAMAGE_TYPE_2, 6, 480);
|
|
|
|
|
if (pMissile->extra > 0)
|
|
|
|
|
{
|
|
|
|
|
actPostSprite(missileActor, kStatDecoration);
|
|
|
|
|
if (pMissile->ang == 1024) sfxPlay3DSound(pMissile, 307, -1, 0);
|
|
|
|
|
pMissile->type = kSpriteDecoration;
|
|
|
|
|
seqSpawn(9, missileActor, -1);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
actPostSprite(pMissile->index, kStatFree);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// by NoOne: allow additional bullet damage for Flare Gun
|
|
|
|
|
if (gGameOptions.weaponsV10x && !VanillaMode() && !DemoRecordStatus()) {
|
|
|
|
|
int nDamage = (20 + Random(10)) << 4;
|
|
|
|
|
actDamageSprite(nOwner, pSpriteHit, DAMAGE_TYPE_2, nDamage);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
int nDamage = (20+Random(10))<<4;
|
|
|
|
|
actDamageSprite(nOwner, pSpriteHit, DAMAGE_TYPE_2, nDamage);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (surfType[pSpriteHit->picnum] == kSurfFlesh) {
|
|
|
|
|
pMissile->picnum = 2123;
|
|
|
|
|
pXMissile->target = nSpriteHit;
|
|
|
|
|
pXMissile->targetZ = pMissile->z-pSpriteHit->z;
|
|
|
|
|
pXMissile->goalAng = getangle(pMissile->x-pSpriteHit->x, pMissile->y-pSpriteHit->y)-pSpriteHit->ang;
|
|
|
|
|
pXMissile->state = 1;
|
|
|
|
|
actPostSprite(pMissile->index, kStatFlare);
|
|
|
|
|
pMissile->cstat &= ~257;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
GibSprite(pMissile, GIBTYPE_17, NULL, NULL);
|
|
|
|
|
actPostSprite(pMissile->index, kStatFree);
|
|
|
|
|
break;
|
|
|
|
|
case kMissileFlameSpray:
|
|
|
|
|
case kMissileFlameHound:
|
|
|
|
|
if (hitCode == 3)
|
|
|
|
|
{
|
|
|
|
|
int nObject = gHitInfo.hitsprite;
|
|
|
|
|
assert(nObject >= 0 && nObject < kMaxSprites);
|
|
|
|
|
spritetype *pObject = &sprite[nObject];
|
|
|
|
|
if (pObject->extra > 0)
|
|
|
|
|
{
|
|
|
|
|
XSPRITE *pXObject = &xsprite[pObject->extra];
|
|
|
|
|
if ((pObject->statnum == kStatThing || pObject->statnum == kStatDude) && pXObject->burnTime == 0)
|
|
|
|
|
evPost(nObject, 3, 0, kCallbackFXFlameLick);
|
|
|
|
|
int nOwner = pMissile->owner;
|
|
|
|
|
actBurnSprite(pMissile->owner, pXObject, (4+gGameOptions.nDifficulty)<<2);
|
|
|
|
|
actDamageSprite(nOwner, pObject, DAMAGE_TYPE_1, 8);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case kMissileFireballCerberus:
|
|
|
|
|
actExplodeSprite(pMissile);
|
|
|
|
|
if (hitCode == 3)
|
|
|
|
|
{
|
|
|
|
|
int nObject = gHitInfo.hitsprite;
|
|
|
|
|
assert(nObject >= 0 && nObject < kMaxSprites);
|
|
|
|
|
spritetype *pObject = &sprite[nObject];
|
|
|
|
|
if (pObject->extra > 0)
|
|
|
|
|
{
|
|
|
|
|
XSPRITE *pXObject = &xsprite[pObject->extra];
|
|
|
|
|
if ((pObject->statnum == kStatThing || pObject->statnum == kStatDude) && pXObject->burnTime == 0)
|
|
|
|
|
evPost(nObject, 3, 0, kCallbackFXFlameLick);
|
|
|
|
|
int nOwner = pMissile->owner;
|
|
|
|
|
actBurnSprite(pMissile->owner, pXObject, (4+gGameOptions.nDifficulty)<<2);
|
|
|
|
|
actDamageSprite(nOwner, pObject, DAMAGE_TYPE_1, 8);
|
|
|
|
|
int nDamage = (25+Random(10))<<4;
|
|
|
|
|
actDamageSprite(nOwner, pObject, DAMAGE_TYPE_2, nDamage);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
actExplodeSprite(pMissile);
|
|
|
|
|
break;
|
|
|
|
|
case kMissileFireballTchernobog:
|
|
|
|
|
actExplodeSprite(pMissile);
|
|
|
|
|
if (hitCode == 3)
|
|
|
|
|
{
|
|
|
|
|
int nObject = gHitInfo.hitsprite;
|
|
|
|
|
assert(nObject >= 0 && nObject < kMaxSprites);
|
|
|
|
|
spritetype *pObject = &sprite[nObject];
|
|
|
|
|
if (pObject->extra > 0)
|
|
|
|
|
{
|
|
|
|
|
XSPRITE *pXObject = &xsprite[pObject->extra];
|
|
|
|
|
if ((pObject->statnum == kStatThing || pObject->statnum == kStatDude) && pXObject->burnTime == 0)
|
|
|
|
|
evPost(nObject, 3, 0, kCallbackFXFlameLick);
|
|
|
|
|
int nOwner = pMissile->owner;
|
|
|
|
|
actBurnSprite(pMissile->owner, pXObject, 32);
|
|
|
|
|
actDamageSprite(nOwner, pObject, DAMAGE_TYPE_5, 12);
|
|
|
|
|
int nDamage = (25+Random(10))<<4;
|
|
|
|
|
actDamageSprite(nOwner, pObject, DAMAGE_TYPE_2, nDamage);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
actExplodeSprite(pMissile);
|
|
|
|
|
break;
|
|
|
|
|
case kMissileEctoSkull:
|
|
|
|
|
sfxKill3DSound(pMissile, -1, -1);
|
|
|
|
|
sfxPlay3DSound(pMissile->x, pMissile->y, pMissile->z, 522, pMissile->sectnum);
|
|
|
|
|
actPostSprite(pMissile->index, kStatDebris);
|
|
|
|
|
seqSpawn(20, 3, pMissile->extra, -1);
|
|
|
|
|
if (hitCode == 3)
|
|
|
|
|
{
|
|
|
|
|
int nObject = gHitInfo.hitsprite;
|
|
|
|
|
assert(nObject >= 0 && nObject < kMaxSprites);
|
|
|
|
|
spritetype *pObject = &sprite[nObject];
|
|
|
|
|
if (pObject->statnum == kStatDude)
|
|
|
|
|
{
|
|
|
|
|
int nOwner = pMissile->owner;
|
|
|
|
|
int nDamage = (25+Random(10))<<4;
|
|
|
|
|
actDamageSprite(nOwner, pObject, DAMAGE_TYPE_5, nDamage);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case kMissileButcherKnife:
|
|
|
|
|
actPostSprite(pMissile->index, kStatDebris);
|
|
|
|
|
pMissile->cstat &= ~16;
|
|
|
|
|
pMissile->type = kSpriteDecoration;
|
|
|
|
|
seqSpawn(20, 3, pMissile->extra, -1);
|
|
|
|
|
if (hitCode == 3)
|
|
|
|
|
{
|
|
|
|
|
int nObject = gHitInfo.hitsprite;
|
|
|
|
|
assert(nObject >= 0 && nObject < kMaxSprites);
|
|
|
|
|
spritetype *pObject = &sprite[nObject];
|
|
|
|
|
if (pObject->statnum == kStatDude)
|
|
|
|
|
{
|
|
|
|
|
int nOwner = pMissile->owner;
|
|
|
|
|
int nDamage = (10+Random(10))<<4;
|
|
|
|
|
actDamageSprite(nOwner, pObject, DAMAGE_TYPE_5, nDamage);
|
|
|
|
|
spritetype *pOwner = &sprite[nOwner];
|
|
|
|
|
XSPRITE *pXOwner = &xsprite[pOwner->extra];
|
|
|
|
|
int nType = pOwner->type-kDudeBase;
|
|
|
|
|
if (pXOwner->health > 0)
|
|
|
|
|
actHealDude(pXOwner, 10, getDudeInfo(nType+kDudeBase)->startHealth);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case kMissileTeslaRegular:
|
|
|
|
|
sfxKill3DSound(pMissile, -1, -1);
|
|
|
|
|
sfxPlay3DSound(pMissile->x, pMissile->y, pMissile->z, 518, pMissile->sectnum);
|
|
|
|
|
GibSprite(pMissile, (hitCode == 2) ? GIBTYPE_23 : GIBTYPE_22, NULL, NULL);
|
|
|
|
|
evKill(pMissile->index, 3);
|
|
|
|
|
seqKill(3, nXMissile);
|
|
|
|
|
actPostSprite(pMissile->index, kStatFree);
|
|
|
|
|
if (hitCode == 3)
|
|
|
|
|
{
|
|
|
|
|
int nObject = gHitInfo.hitsprite;
|
|
|
|
|
assert(nObject >= 0 && nObject < kMaxSprites);
|
|
|
|
|
spritetype *pObject = &sprite[nObject];
|
|
|
|
|
int nOwner = pMissile->owner;
|
|
|
|
|
int nDamage = (15+Random(10))<<4;
|
|
|
|
|
actDamageSprite(nOwner, pObject, DAMAGE_TYPE_6, nDamage);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
seqKill(3, nXMissile);
|
|
|
|
|
actPostSprite(pMissile->index, kStatFree);
|
|
|
|
|
if (hitCode == 3)
|
|
|
|
|
{
|
|
|
|
|
int nObject = gHitInfo.hitsprite;
|
|
|
|
|
assert(nObject >= 0 && nObject < kMaxSprites);
|
|
|
|
|
spritetype *pObject = &sprite[nObject];
|
|
|
|
|
int nOwner = pMissile->owner;
|
|
|
|
|
int nDamage = (10+Random(10))<<4;
|
|
|
|
|
actDamageSprite(nOwner, pObject, DAMAGE_TYPE_0, nDamage);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef NOONE_EXTENSIONS
|
|
|
|
|
if (gModernMap && pXSpriteHit && pXSpriteHit->state != pXSpriteHit->restState && pXSpriteHit->Impact)
|
|
|
|
|
trTriggerSprite(nSpriteHit, pXSpriteHit, kCmdSpriteImpact);
|
|
|
|
|
#endif
|
|
|
|
|
pMissile->cstat &= ~257;
|
|
|
|
|
break;
|
|
|
|
|
case kMissileTeslaAlt:
|
|
|
|
|
teslaHit(pMissile, hitCode);
|
|
|
|
|
switch (hitCode)
|
|
|
|
|
{
|
|
|
|
|
case 0:
|
|
|
|
|
case 4:
|
|
|
|
|
if (pWallHit)
|
|
|
|
|
{
|
|
|
|
|
spritetype* pFX = gFX.fxSpawn(FX_52, pMissile->sectnum, pMissile->x, pMissile->y, pMissile->z, 0);
|
|
|
|
|
if (pFX) pFX->ang = (GetWallAngle(pWallHit) + 512) & 2047;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
GibSprite(pMissile, GIBTYPE_24, NULL, NULL);
|
|
|
|
|
actPostSprite(missileActor, kStatFree);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case kMissilePukeGreen:
|
|
|
|
|
seqKill(missileActor);
|
|
|
|
|
if (hitCode == 3 && pSpriteHit && (pThingInfo || pDudeInfo))
|
|
|
|
|
{
|
|
|
|
|
int nOwner = pMissile->owner;
|
|
|
|
|
int nDamage = (15 + Random(7)) << 4;
|
|
|
|
|
actDamageSprite(nOwner, pSpriteHit, DAMAGE_TYPE_2, nDamage);
|
|
|
|
|
}
|
|
|
|
|
actPostSprite(missileActor, kStatFree);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case kMissileArcGargoyle:
|
|
|
|
|
sfxKill3DSound(pMissile, -1, -1);
|
|
|
|
|
sfxPlay3DSound(pMissile->x, pMissile->y, pMissile->z, 306, pMissile->sectnum);
|
|
|
|
|
GibSprite(pMissile, GIBTYPE_6, NULL, NULL);
|
|
|
|
|
|
|
|
|
|
if (hitCode == 3 && pSpriteHit && (pThingInfo || pDudeInfo))
|
|
|
|
|
{
|
|
|
|
|
int nDamage = (25 + Random(20)) << 4;
|
|
|
|
|
actDamageSprite(missileOwner, actorHit, DAMAGE_TYPE_5, nDamage);
|
|
|
|
|
}
|
|
|
|
|
actPostSprite(missileActor, kStatFree);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case kMissileLifeLeechAltNormal:
|
|
|
|
|
case kMissileLifeLeechAltSmall:
|
|
|
|
|
sfxKill3DSound(pMissile, -1, -1);
|
|
|
|
|
sfxPlay3DSound(pMissile->x, pMissile->y, pMissile->z, 306, pMissile->sectnum);
|
|
|
|
|
|
|
|
|
|
if (hitCode == 3 && pSpriteHit && (pThingInfo || pDudeInfo))
|
|
|
|
|
{
|
|
|
|
|
int nDmgMul = (pMissile->type == kMissileLifeLeechAltSmall) ? 6 : 3;
|
|
|
|
|
int nDamage = (nDmgMul + Random(nDmgMul)) << 4;
|
|
|
|
|
actDamageSprite(missileOwner, actorHit, DAMAGE_TYPE_5, nDamage);
|
|
|
|
|
}
|
|
|
|
|
actPostSprite(missileActor, kStatFree);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case kMissileFireball:
|
|
|
|
|
case kMissileFireballNapam:
|
|
|
|
|
if (hitCode == 3 && pSpriteHit && (pThingInfo || pDudeInfo))
|
|
|
|
|
{
|
|
|
|
|
if (pThingInfo && pSpriteHit->type == kThingTNTBarrel && actorHit->x().burnTime == 0)
|
|
|
|
|
evPost(actorHit, 0, kCallbackFXFlameLick);
|
|
|
|
|
|
|
|
|
|
int nDamage = (50 + Random(50)) << 4;
|
|
|
|
|
actDamageSprite(missileOwner, actorHit, DAMAGE_TYPE_2, nDamage);
|
|
|
|
|
}
|
|
|
|
|
actExplodeSprite(pMissile);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case kMissileFlareAlt:
|
|
|
|
|
sfxKill3DSound(pMissile, -1, -1);
|
|
|
|
|
actExplodeSprite(pMissile);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case kMissileFlareRegular:
|
|
|
|
|
sfxKill3DSound(pMissile, -1, -1);
|
|
|
|
|
if ((hitCode == 3 && pSpriteHit) && (pThingInfo || pDudeInfo))
|
|
|
|
|
{
|
|
|
|
|
if ((pThingInfo && pThingInfo->dmgControl[DAMAGE_TYPE_1] != 0) || (pDudeInfo && pDudeInfo->damageVal[DAMAGE_TYPE_1] != 0))
|
|
|
|
|
{
|
|
|
|
|
if (pThingInfo && pSpriteHit->type == kThingTNTBarrel && actorHit->x().burnTime == 0)
|
|
|
|
|
evPost(actorHit, 0, kCallbackFXFlameLick);
|
|
|
|
|
|
|
|
|
|
actBurnSprite(missileOwner, actorHit, 480);
|
|
|
|
|
actRadiusDamage(missileOwner, pMissile->x, pMissile->y, pMissile->z, pMissile->sectnum, 16, 20, 10, DAMAGE_TYPE_2, 6, 480);
|
|
|
|
|
|
|
|
|
|
// by NoOne: allow additional bullet damage for Flare Gun
|
|
|
|
|
if (gGameOptions.weaponsV10x && !VanillaMode() && !DemoRecordStatus())
|
|
|
|
|
{
|
|
|
|
|
int nDamage = (20 + Random(10)) << 4;
|
|
|
|
|
actDamageSprite(missileOwner, actorHit, DAMAGE_TYPE_2, nDamage);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
int nDamage = (20 + Random(10)) << 4;
|
|
|
|
|
actDamageSprite(missileOwner, actorHit, DAMAGE_TYPE_2, nDamage);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (surfType[pSpriteHit->picnum] == kSurfFlesh)
|
|
|
|
|
{
|
|
|
|
|
pMissile->picnum = 2123;
|
|
|
|
|
missileActor->SetTarget(actorHit);
|
|
|
|
|
pXMissile->targetZ = pMissile->z - pSpriteHit->z;
|
|
|
|
|
pXMissile->goalAng = getangle(pMissile->x - pSpriteHit->x, pMissile->y - pSpriteHit->y) - pSpriteHit->ang;
|
|
|
|
|
pXMissile->state = 1;
|
|
|
|
|
actPostSprite(pMissile->index, kStatFlare);
|
|
|
|
|
pMissile->cstat &= ~257;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
GibSprite(pMissile, GIBTYPE_17, NULL, NULL);
|
|
|
|
|
actPostSprite(missileActor, kStatFree);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case kMissileFlameSpray:
|
|
|
|
|
case kMissileFlameHound:
|
|
|
|
|
if (hitCode == 3 && actorHit && actorHit->hasX())
|
|
|
|
|
{
|
|
|
|
|
if ((pSpriteHit->statnum == kStatThing || pSpriteHit->statnum == kStatDude) && pXSpriteHit->burnTime == 0)
|
|
|
|
|
evPost(actorHit, 0, kCallbackFXFlameLick);
|
|
|
|
|
|
|
|
|
|
actBurnSprite(missileOwner, actorHit, (4 + gGameOptions.nDifficulty) << 2);
|
|
|
|
|
actDamageSprite(missileOwner, actorHit, DAMAGE_TYPE_1, 8);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case kMissileFireballCerberus:
|
|
|
|
|
actExplodeSprite(pMissile);
|
|
|
|
|
if (hitCode == 3 && actorHit && actorHit->hasX())
|
|
|
|
|
{
|
|
|
|
|
if ((pSpriteHit->statnum == kStatThing || pSpriteHit->statnum == kStatDude) && pXSpriteHit->burnTime == 0)
|
|
|
|
|
evPost(actorHit, 0, kCallbackFXFlameLick);
|
|
|
|
|
|
|
|
|
|
actBurnSprite(missileOwner, actorHit, (4 + gGameOptions.nDifficulty) << 2);
|
|
|
|
|
actDamageSprite(missileOwner, actorHit, DAMAGE_TYPE_1, 8);
|
|
|
|
|
int nDamage = (25 + Random(10)) << 4;
|
|
|
|
|
actDamageSprite(missileOwner, actorHit, DAMAGE_TYPE_2, nDamage);
|
|
|
|
|
}
|
|
|
|
|
actExplodeSprite(pMissile);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case kMissileFireballTchernobog:
|
|
|
|
|
actExplodeSprite(pMissile);
|
|
|
|
|
if (hitCode == 3 && actorHit && actorHit->hasX())
|
|
|
|
|
{
|
|
|
|
|
if ((pSpriteHit->statnum == kStatThing || pSpriteHit->statnum == kStatDude) && pXSpriteHit->burnTime == 0)
|
|
|
|
|
evPost(actorHit, 0, kCallbackFXFlameLick);
|
|
|
|
|
|
|
|
|
|
actBurnSprite(missileOwner, actorHit, 32);
|
|
|
|
|
actDamageSprite(missileOwner, actorHit, DAMAGE_TYPE_5, 12);
|
|
|
|
|
int nDamage = (25 + Random(10)) << 4;
|
|
|
|
|
actDamageSprite(missileOwner, actorHit, DAMAGE_TYPE_2, nDamage);
|
|
|
|
|
}
|
|
|
|
|
actExplodeSprite(pMissile);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case kMissileEctoSkull:
|
|
|
|
|
sfxKill3DSound(pMissile, -1, -1);
|
|
|
|
|
sfxPlay3DSound(pMissile->x, pMissile->y, pMissile->z, 522, pMissile->sectnum);
|
|
|
|
|
actPostSprite(pMissile->index, kStatDebris);
|
|
|
|
|
seqSpawn(20, 3, pMissile->extra, -1);
|
|
|
|
|
if (hitCode == 3 && actorHit && actorHit->hasX())
|
|
|
|
|
{
|
|
|
|
|
if (pSpriteHit->statnum == kStatDude)
|
|
|
|
|
{
|
|
|
|
|
int nDamage = (25 + Random(10)) << 4;
|
|
|
|
|
actDamageSprite(missileOwner, actorHit, DAMAGE_TYPE_5, nDamage);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case kMissileButcherKnife:
|
|
|
|
|
actPostSprite(missileActor, kStatDebris);
|
|
|
|
|
pMissile->cstat &= ~16;
|
|
|
|
|
pMissile->type = kSpriteDecoration;
|
|
|
|
|
seqSpawn(20, 3, pMissile->extra, -1);
|
|
|
|
|
if (hitCode == 3 && actorHit && actorHit->hasX())
|
|
|
|
|
{
|
|
|
|
|
if (pSpriteHit->statnum == kStatDude)
|
|
|
|
|
{
|
|
|
|
|
int nDamage = (10 + Random(10)) << 4;
|
|
|
|
|
actDamageSprite(missileOwner, actorHit, DAMAGE_TYPE_5, nDamage);
|
|
|
|
|
int nType = missileOwner->s().type - kDudeBase;
|
|
|
|
|
if (missileOwner->x().health > 0)
|
|
|
|
|
actHealDude(missileOwner, 10, getDudeInfo(nType + kDudeBase)->startHealth);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case kMissileTeslaRegular:
|
|
|
|
|
sfxKill3DSound(pMissile, -1, -1);
|
|
|
|
|
sfxPlay3DSound(pMissile->x, pMissile->y, pMissile->z, 518, pMissile->sectnum);
|
|
|
|
|
GibSprite(pMissile, (hitCode == 2) ? GIBTYPE_23 : GIBTYPE_22, NULL, NULL);
|
|
|
|
|
evKill(missileActor);
|
|
|
|
|
seqKill(missileActor);
|
|
|
|
|
actPostSprite(missileActor, kStatFree);
|
|
|
|
|
if (hitCode == 3 && actorHit)
|
|
|
|
|
{
|
|
|
|
|
int nDamage = (15 + Random(10)) << 4;
|
|
|
|
|
actDamageSprite(missileOwner, actorHit, DAMAGE_TYPE_6, nDamage);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
seqKill(missileActor);
|
|
|
|
|
actPostSprite(missileActor, kStatFree);
|
|
|
|
|
if (hitCode == 3 && actorHit)
|
|
|
|
|
{
|
|
|
|
|
int nDamage = (10 + Random(10)) << 4;
|
|
|
|
|
actDamageSprite(missileOwner, actorHit, DAMAGE_TYPE_0, nDamage);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef NOONE_EXTENSIONS
|
|
|
|
|
if (gModernMap && pXSpriteHit && pXSpriteHit->state != pXSpriteHit->restState && pXSpriteHit->Impact)
|
|
|
|
|
trTriggerSprite(actorHit, kCmdSpriteImpact);
|
|
|
|
|
#endif
|
|
|
|
|
pMissile->cstat &= ~257;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void actKickObject(spritetype *pSprite1, spritetype *pSprite2)
|
|
|
|
@ -4825,7 +4783,7 @@ void MoveDude(spritetype *pSprite)
|
|
|
|
|
{
|
|
|
|
|
HITINFO hitInfo = gHitInfo;
|
|
|
|
|
gHitInfo.hitsprite = nSprite;
|
|
|
|
|
actImpactMissile(pHitSprite, 3);
|
|
|
|
|
actImpactMissile(&bloodActors[nHitSprite], 3);
|
|
|
|
|
gHitInfo = hitInfo;
|
|
|
|
|
}
|
|
|
|
|
#ifdef NOONE_EXTENSIONS
|
|
|
|
@ -5893,7 +5851,7 @@ void actProcessSprites(void)
|
|
|
|
|
viewBackupSpriteLoc(nSprite, pSprite);
|
|
|
|
|
int hit = MoveMissile(pSprite);
|
|
|
|
|
if (hit >= 0)
|
|
|
|
|
actImpactMissile(pSprite, hit);
|
|
|
|
|
actImpactMissile(&bloodActors[pSprite->index], hit);
|
|
|
|
|
}
|
|
|
|
|
it.Reset(kStatExplosion);
|
|
|
|
|
while ((nSprite = it.NextIndex()) >= 0)
|
|
|
|
@ -6597,7 +6555,7 @@ spritetype* actFireMissile(spritetype *pSprite, int a2, int a3, int a4, int a5,
|
|
|
|
|
|
|
|
|
|
if (v4)
|
|
|
|
|
{
|
|
|
|
|
actImpactMissile(pMissile, hit);
|
|
|
|
|
actImpactMissile(&bloodActors[pMissile->index], hit);
|
|
|
|
|
pMissile = NULL;
|
|
|
|
|
}
|
|
|
|
|
return pMissile;
|
|
|
|
|