- split up actKillSprite into several smaller functions.

The biggest problem in here was tracking the lifetime of local variables.
This commit is contained in:
Christoph Oelckers 2020-12-03 00:20:14 +01:00
parent 36b910a253
commit 965939957e
4 changed files with 648 additions and 499 deletions

View file

@ -2438,7 +2438,7 @@ static void actInitDudes()
{ {
spritetype* pSprite = &act->s(); spritetype* pSprite = &act->s();
if (act->hasX() && act->x().key > 0) // Drop Key if (act->hasX() && act->x().key > 0) // Drop Key
actDropObject(pSprite, kItemKeyBase + (act->x().key - 1)); actDropObject(act, kItemKeyBase + (act->x().key - 1));
DeleteSprite(act); DeleteSprite(act);
} }
} }
@ -2938,6 +2938,7 @@ bool actHealDude(DBloodActor *actor, int add, int threshold)
// //
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
#ifdef NOONE_EXTENSIONS #ifdef NOONE_EXTENSIONS
static bool actKillModernDude(DBloodActor* actor, DAMAGE_TYPE damageType) static bool actKillModernDude(DBloodActor* actor, DAMAGE_TYPE damageType)
{ {
@ -3031,26 +3032,27 @@ static bool actKillModernDude(DBloodActor* actor, DAMAGE_TYPE damageType)
} }
#endif #endif
void actKillDude(int nKillerSprite, spritetype *pSprite, DAMAGE_TYPE damageType, int damage) //---------------------------------------------------------------------------
{ //
auto actor = &bloodActors[pSprite->index]; //
spritetype *pKillerSprite = &sprite[nKillerSprite]; //
assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); //---------------------------------------------------------------------------
int nType = pSprite->type-kDudeBase;
int nXSprite = pSprite->extra;
assert(nXSprite > 0);
XSPRITE *pXSprite = &xsprite[pSprite->extra];
static bool actKillDudeStage1(DBloodActor* actor,DAMAGE_TYPE damageType)
{
auto pSprite = &actor->s();
auto pXSprite = &actor->x();
switch (pSprite->type) switch (pSprite->type)
{ {
#ifdef NOONE_EXTENSIONS #ifdef NOONE_EXTENSIONS
case kDudeModernCustom: case kDudeModernCustom:
if (actKillModernDude(actor, damageType)) return; if (actKillModernDude(actor, damageType)) return true;
break; break;
#endif #endif
case kDudeCerberusTwoHead: // Cerberus case kDudeCerberusTwoHead: // Cerberus
seqSpawn(dudeInfo[nType].seqStartID+1, 3, nXSprite, -1); seqSpawn(dudeInfo[pSprite->type - kDudeBase].seqStartID + 1, actor, -1);
return; return true;
case kDudeCultistTommy: case kDudeCultistTommy:
case kDudeCultistShotgun: case kDudeCultistShotgun:
case kDudeCultistTesla: case kDudeCultistTesla:
@ -3060,47 +3062,56 @@ void actKillDude(int nKillerSprite, spritetype *pSprite, DAMAGE_TYPE damageType,
pSprite->type = kDudeBurningCultist; pSprite->type = kDudeBurningCultist;
aiNewState(actor, &cultistBurnGoto); aiNewState(actor, &cultistBurnGoto);
actHealDude(actor, dudeInfo[40].startHealth, dudeInfo[40].startHealth); actHealDude(actor, dudeInfo[40].startHealth, dudeInfo[40].startHealth);
return; return true;
} }
// no break break;
fallthrough__;
case kDudeBeast: case kDudeBeast:
if (damageType == DAMAGE_TYPE_1 && pXSprite->medium == kMediumNormal) if (damageType == DAMAGE_TYPE_1 && pXSprite->medium == kMediumNormal)
{ {
pSprite->type = kDudeBurningBeast; pSprite->type = kDudeBurningBeast;
aiNewState(actor, &beastBurnGoto); aiNewState(actor, &beastBurnGoto);
actHealDude(actor, dudeInfo[53].startHealth, dudeInfo[53].startHealth); actHealDude(actor, dudeInfo[53].startHealth, dudeInfo[53].startHealth);
return; return true;
} }
// no break break;
fallthrough__;
case kDudeInnocent: case kDudeInnocent:
if (damageType == DAMAGE_TYPE_1 && pXSprite->medium == kMediumNormal) if (damageType == DAMAGE_TYPE_1 && pXSprite->medium == kMediumNormal)
{ {
pSprite->type = kDudeBurningInnocent; pSprite->type = kDudeBurningInnocent;
aiNewState(actor, &innocentBurnGoto); aiNewState(actor, &innocentBurnGoto);
actHealDude(actor, dudeInfo[39].startHealth, dudeInfo[39].startHealth); actHealDude(actor, dudeInfo[39].startHealth, dudeInfo[39].startHealth);
return; return true;
} }
break; break;
} }
for (int p = connecthead; p >= 0; p = connectpoint2[p]) return false;
{
if (gPlayer[p].fraggerId == pSprite->index && gPlayer[p].deathTime > 0)
gPlayer[p].fraggerId = -1;
} }
if (pSprite->type != kDudeCultistBeast)
trTriggerSprite(pSprite->index, pXSprite, kCmdOff);
pSprite->flags |= 7; //---------------------------------------------------------------------------
if (VanillaMode()) { //
if (IsPlayerSprite(pKillerSprite)) { //
//
//---------------------------------------------------------------------------
static void checkAddFrag(DBloodActor* killerActor, DBloodActor* actor)
{
auto pKillerSprite = &killerActor->s();
auto pSprite = &actor->s();
if (VanillaMode())
{
if (killerActor->IsPlayerActor())
{
PLAYER* pPlayer = &gPlayer[pKillerSprite->type - kDudePlayer1]; PLAYER* pPlayer = &gPlayer[pKillerSprite->type - kDudePlayer1];
if (gGameOptions.nGameType == 1) if (gGameOptions.nGameType == 1)
pPlayer->fragCount++; pPlayer->fragCount++;
} }
} else if (gGameOptions.nGameType == 1 && IsPlayerSprite(pKillerSprite) && pSprite->statnum == kStatDude) { }
switch (pSprite->type) { else if (gGameOptions.nGameType == 1 && killerActor->IsPlayerActor() && pSprite->statnum == kStatDude)
{
switch (pSprite->type)
{
case kDudeBat: case kDudeBat:
case kDudeRat: case kDudeRat:
case kDudeInnocent: case kDudeInnocent:
@ -3113,41 +3124,67 @@ void actKillDude(int nKillerSprite, spritetype *pSprite, DAMAGE_TYPE damageType,
} }
} }
if (pXSprite->key > 0)
actDropObject(pSprite, kItemKeyBase + pXSprite->key - 1);
if (pXSprite->dropMsg > 0)
actDropObject(pSprite, pXSprite->dropMsg);
switch (pSprite->type) {
case kDudeCultistTommy: {
int nRand = Random(100);
if (nRand < 10) actDropObject(pSprite, kItemWeaponTommygun);
else if (nRand < 50) actDropObject(pSprite, kItemAmmoTommygunFew);
} }
break;
case kDudeCultistShotgun: { //---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static void checkDropObjects(DBloodActor* actor)
{
auto pXSprite = &actor->x();
if (pXSprite->key > 0) actDropObject(actor, kItemKeyBase + pXSprite->key - 1);
if (pXSprite->dropMsg > 0) actDropObject(actor, pXSprite->dropMsg);
switch (actor->s().type)
{
case kDudeCultistTommy:
{
int nRand = Random(100); int nRand = Random(100);
if (nRand <= 10) actDropObject(pSprite, kItemWeaponSawedoff); if (nRand < 10) actDropObject(actor, kItemWeaponTommygun);
else if (nRand <= 50) actDropObject(pSprite, kItemAmmoSawedoffFew); else if (nRand < 50) actDropObject(actor, kItemAmmoTommygunFew);
}
break; break;
} }
case kDudeCultistShotgun:
{
int nRand = Random(100);
if (nRand <= 10) actDropObject(actor, kItemWeaponSawedoff);
else if (nRand <= 50) actDropObject(actor, kItemAmmoSawedoffFew);
break;
}
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static int checkDamageType(DBloodActor* actor, DAMAGE_TYPE damageType)
{
int nSeq; int nSeq;
auto pSprite = &actor->s();
switch (damageType) switch (damageType)
{ {
case DAMAGE_TYPE_3: case DAMAGE_TYPE_3:
nSeq = 2; nSeq = 2;
switch (pSprite->type) { switch (pSprite->type)
{
#ifdef NOONE_EXTENSIONS #ifdef NOONE_EXTENSIONS
case kDudeModernCustom: case kDudeModernCustom:
case kDudeModernCustomBurning: { case kDudeModernCustomBurning:
{
playGenDudeSound(pSprite, kGenDudeSndDeathExplode); playGenDudeSound(pSprite, kGenDudeSndDeathExplode);
GENDUDEEXTRA* pExtra = genDudeExtra(pSprite); GENDUDEEXTRA* pExtra = &actor->genDudeExtra();
if (!pExtra->availDeaths[damageType]) { if (!pExtra->availDeaths[damageType])
nSeq = 1; damageType = DAMAGE_TYPE_0; {
nSeq = 1;
damageType = DAMAGE_TYPE_0;
} }
break; break;
} }
@ -3202,320 +3239,408 @@ void actKillDude(int nKillerSprite, spritetype *pSprite, DAMAGE_TYPE damageType,
nSeq = 1; nSeq = 1;
break; break;
} }
return nSeq;
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static void spawnGibs(DBloodActor* actor, int type, int velz)
{
int top, bottom;
GetActorExtents(actor, &top, &bottom);
CGibPosition gibPos(actor->s().x, actor->s().y, top);
CGibVelocity gibVel(actor->xvel() >> 1, actor->yvel() >> 1, velz);
GibSprite(&actor->s(), GIBTYPE_27, &gibPos, &gibVel);
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static void zombieAxeNormalDeath(DBloodActor* actor, int nSeq)
{
auto pSprite = &actor->s();
int nType = pSprite->type - kDudeBase;
sfxPlay3DSound(pSprite, 1107 + Random(2), -1, 0);
if (nSeq == 2)
{
seqSpawn(dudeInfo[nType].seqStartID + nSeq, actor, nDudeToGibClient1);
spawnGibs(actor, GIBTYPE_27, -0xccccc);
}
else if (nSeq == 1 && Chance(0x4000))
{
seqSpawn(dudeInfo[nType].seqStartID + 7, actor, nDudeToGibClient1);
evPost(pSprite->index, 3, 0, kCallbackFXZombieSpurt);
sfxPlay3DSound(pSprite, 362, -1, 0);
actor->x().data1 = 35;
actor->x().data2 = 5;
spawnGibs(actor, GIBTYPE_27, -0x111111);
}
else if (nSeq == 14)seqSpawn(dudeInfo[nType].seqStartID + nSeq, actor, -1);
else if (nSeq == 3) seqSpawn(dudeInfo[nType].seqStartID + 13, actor, nDudeToGibClient2);
else seqSpawn(dudeInfo[nType].seqStartID + nSeq, actor, nDudeToGibClient1);
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static void burningCultistDeath(DBloodActor* actor, int nSeq)
{
auto pSprite = &actor->s();
if (Chance(0x4000) && nSeq == 3) sfxPlay3DSound(pSprite, 718, -1, 0);
else sfxPlay3DSound(pSprite, 1018 + Random(2), -1, 0);
int nType = pSprite->type - kDudeBase;
if (Chance(0x8000))
{
for (int i = 0; i < 3; i++)
GibSprite(pSprite, GIBTYPE_7, NULL, NULL);
seqSpawn(dudeInfo[nType].seqStartID + 16 - Random(1), actor, nDudeToGibClient1);
}
else
seqSpawn(dudeInfo[nType].seqStartID + 15, actor, nDudeToGibClient2);
}
#ifdef NOONE_EXTENSIONS
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static void modernCustomDudeDeath(DBloodActor* actor, int nSeq, int damageType)
{
auto pSprite = &actor->s();
auto pXSprite = &actor->x();
playGenDudeSound(pSprite, kGenDudeSndDeathNormal);
int dudeToGib = (actCheckRespawn(pSprite)) ? -1 : ((nSeq == 3) ? nDudeToGibClient2 : nDudeToGibClient1);
if (nSeq == 3)
{
GENDUDEEXTRA* pExtra = genDudeExtra(pSprite);
if (pExtra->availDeaths[kDmgBurn] == 3) seqSpawn((15 + Random(2)) + pXSprite->data2, actor, dudeToGib);
else if (pExtra->availDeaths[kDmgBurn] == 2) seqSpawn(16 + pXSprite->data2, actor, dudeToGib);
else if (pExtra->availDeaths[kDmgBurn] == 1) seqSpawn(15 + pXSprite->data2, actor, dudeToGib);
else if (getSequence(pXSprite->data2 + nSeq))seqSpawn(nSeq + pXSprite->data2, actor, dudeToGib);
else seqSpawn(1 + pXSprite->data2, actor, dudeToGib);
}
else
{
seqSpawn(nSeq + pXSprite->data2, actor, dudeToGib);
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static void modernCustomDudeBurningDeath(DBloodActor* actor, int nSeq)
{
auto pSprite = &actor->s();
playGenDudeSound(pSprite, kGenDudeSndDeathExplode);
int dudeToGib = (actCheckRespawn(pSprite)) ? -1 : nDudeToGibClient1;
if (Chance(0x4000)) spawnGibs(actor, GIBTYPE_27, -0xccccc);
GENDUDEEXTRA* pExtra = &actor->genDudeExtra();
int seqofs = actor->x().data2;
if (pExtra->availDeaths[kDmgBurn] == 3) seqSpawn((15 + Random(2)) + seqofs, actor, dudeToGib);
else if (pExtra->availDeaths[kDmgBurn] == 2) seqSpawn(16 + seqofs, actor, dudeToGib);
else if (pExtra->availDeaths[kDmgBurn] == 1) seqSpawn(15 + seqofs, actor, dudeToGib);
else seqSpawn(1 + seqofs, actor, dudeToGib);
}
#endif
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void zombieAxeBurningDeath(DBloodActor* actor, int nSeq)
{
auto pSprite = &actor->s();
int nType = pSprite->type - kDudeBase;
if (Chance(0x8000) && nSeq == 3)
sfxPlay3DSound(pSprite, 1109, -1, 0);
else
sfxPlay3DSound(pSprite, 1107 + Random(2), -1, 0);
if (Chance(0x8000))
{
seqSpawn(dudeInfo[nType].seqStartID + 13, actor, nDudeToGibClient1);
spawnGibs(actor, GIBTYPE_27, -0xccccc);
}
else
seqSpawn(dudeInfo[nType].seqStartID + 13, actor, nDudeToGibClient2);
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static void zombieButcherDeath(DBloodActor* actor, int nSeq)
{
auto pSprite = &actor->s();
int nType = pSprite->type - kDudeBase;
if (nSeq == 14)
{
sfxPlay3DSound(pSprite, 1206, -1, 0);
seqSpawn(dudeInfo[nType].seqStartID + 11, actor, -1);
return;
}
sfxPlay3DSound(pSprite, 1204 + Random(2), -1, 0);
if (nSeq == 3)
seqSpawn(dudeInfo[nType].seqStartID + 10, actor, -1);
else
seqSpawn(dudeInfo[nType].seqStartID + nSeq, actor, -1);
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static void genericDeath(DBloodActor* actor, int nSeq, int sound1, int seqnum)
{
auto pSprite = &actor->s();
if (Chance(0x4000) && nSeq == 3) sfxPlay3DSound(pSprite, sound1 + 2, -1, 0);
else sfxPlay3DSound(pSprite, sound1 + Random(2), -1, 0);
seqSpawn(seqnum, actor, -1);
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void actKillDude(DBloodActor* killerActor, DBloodActor* actor, DAMAGE_TYPE damageType, int damage)
{
spritetype *pKillerSprite = &killerActor->s();
auto pSprite = &actor->s();
assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax && actor->hasX());
int nType = pSprite->type-kDudeBase;
XSPRITE *pXSprite = &actor->x();
if (actKillDudeStage1(actor, damageType)) return;
for (int p = connecthead; p >= 0; p = connectpoint2[p])
{
if (gPlayer[p].fragger() == actor && gPlayer[p].deathTime > 0)
gPlayer[p].setFragger(nullptr);
}
if (pSprite->type != kDudeCultistBeast)
trTriggerSprite(pSprite->index, pXSprite, kCmdOff);
pSprite->flags |= 7;
checkAddFrag(killerActor, actor);
checkDropObjects(actor);
int nSeq = checkDamageType(actor, damageType);
if (!getSequence(getDudeInfo(nType+kDudeBase)->seqStartID + nSeq)) if (!getSequence(getDudeInfo(nType+kDudeBase)->seqStartID + nSeq))
{ {
seqKill(3, nXSprite); seqKill(actor);
gKillMgr.AddKill(pSprite); gKillMgr.AddKill(pSprite);
actPostSprite(pSprite->index, kStatFree); actPostSprite(actor, kStatFree);
return; return;
} }
switch (pSprite->type) { switch (pSprite->type)
{
case kDudeZombieAxeNormal: case kDudeZombieAxeNormal:
sfxPlay3DSound(pSprite, 1107+Random(2), -1, 0); zombieAxeNormalDeath(actor, nSeq);
if (nSeq == 2) {
seqSpawn(dudeInfo[nType].seqStartID+nSeq, 3, nXSprite, nDudeToGibClient1);
int top, bottom;
GetSpriteExtents(pSprite, &top, &bottom);
CGibPosition gibPos(pSprite->x, pSprite->y, top);
CGibVelocity gibVel(xvel[pSprite->index]>>1, yvel[pSprite->index]>>1, -0xccccc);
GibSprite(pSprite, GIBTYPE_27, &gibPos, &gibVel);
} else if (nSeq == 1 && Chance(0x4000)) {
seqSpawn(dudeInfo[nType].seqStartID+7, 3, nXSprite, nDudeToGibClient1);
evPost(pSprite->index, 3, 0, kCallbackFXZombieSpurt);
sfxPlay3DSound(pSprite, 362, -1, 0);
pXSprite->data1 = 35;
pXSprite->data2 = 5;
int top, bottom;
GetSpriteExtents(pSprite, &top, &bottom);
CGibPosition gibPos(pSprite->x, pSprite->y, top);
CGibVelocity gibVel(xvel[pSprite->index] >> 1, yvel[pSprite->index] >> 1, -0x111111);
GibSprite(pSprite, GIBTYPE_27, &gibPos, &gibVel);
} else if (nSeq == 14)
seqSpawn(dudeInfo[nType].seqStartID+nSeq, 3, nXSprite, -1);
else if (nSeq == 3)
seqSpawn(dudeInfo[nType].seqStartID+13, 3, nXSprite, nDudeToGibClient2);
else
seqSpawn(dudeInfo[nType].seqStartID+nSeq, 3, nXSprite, nDudeToGibClient1);
break; break;
case kDudeCultistTommy: case kDudeCultistTommy:
case kDudeCultistShotgun: case kDudeCultistShotgun:
case kDudeCultistTesla: case kDudeCultistTesla:
case kDudeCultistTNT: case kDudeCultistTNT:
sfxPlay3DSound(pSprite, 1018+Random(2), -1, 0); sfxPlay3DSound(pSprite, 1018+Random(2), -1, 0);
if (nSeq == 3) seqSpawn(dudeInfo[nType].seqStartID+nSeq, actor, nSeq == 3? nDudeToGibClient2 : nDudeToGibClient1);
seqSpawn(dudeInfo[nType].seqStartID+nSeq, 3, nXSprite, nDudeToGibClient2);
else
seqSpawn(dudeInfo[nType].seqStartID+nSeq, 3, nXSprite, nDudeToGibClient1);
break; break;
case kDudeBurningCultist: case kDudeBurningCultist:
if (Chance(0x4000) && nSeq == 3) burningCultistDeath(actor, nSeq);
sfxPlay3DSound(pSprite, 718, -1, 0);
else
sfxPlay3DSound(pSprite, 1018+Random(2), -1, 0);
damageType = DAMAGE_TYPE_3; damageType = DAMAGE_TYPE_3;
if (Chance(0x8000))
{
for (int i = 0; i < 3; i++)
GibSprite(pSprite, GIBTYPE_7, NULL, NULL);
seqSpawn(dudeInfo[nType].seqStartID+16-Random(1), 3, nXSprite, nDudeToGibClient1);
}
else
seqSpawn(dudeInfo[nType].seqStartID+15, 3, nXSprite, nDudeToGibClient2);
break; break;
#ifdef NOONE_EXTENSIONS #ifdef NOONE_EXTENSIONS
case kDudeModernCustom: { case kDudeModernCustom:
playGenDudeSound(pSprite, kGenDudeSndDeathNormal); modernCustomDudeDeath(actor, nSeq, damageType);
int dudeToGib = (actCheckRespawn(pSprite)) ? -1 : ((nSeq == 3) ? nDudeToGibClient2 : nDudeToGibClient1);
if (nSeq == 3) {
GENDUDEEXTRA* pExtra = genDudeExtra(pSprite);
if (pExtra->availDeaths[kDmgBurn] == 3) seqSpawn((15 + Random(2)) + pXSprite->data2, 3, nXSprite, dudeToGib);
else if (pExtra->availDeaths[kDmgBurn] == 2) seqSpawn(16 + pXSprite->data2, 3, nXSprite, dudeToGib);
else if (pExtra->availDeaths[kDmgBurn] == 1) seqSpawn(15 + pXSprite->data2, 3, nXSprite, dudeToGib);
else if (getSequence(pXSprite->data2 + nSeq))seqSpawn(nSeq + pXSprite->data2, 3, nXSprite, dudeToGib);
else seqSpawn(1 + pXSprite->data2, 3, nXSprite, dudeToGib);
} else {
seqSpawn(nSeq + pXSprite->data2, 3, nXSprite, dudeToGib);
}
genDudePostDeath(pSprite, damageType, damage); genDudePostDeath(pSprite, damageType, damage);
return; return;
} case kDudeModernCustomBurning:
case kDudeModernCustomBurning: { modernCustomDudeBurningDeath(actor, nSeq);
playGenDudeSound(pSprite, kGenDudeSndDeathExplode); genDudePostDeath(pSprite, DAMAGE_TYPE_3, damage);
int dudeToGib = (actCheckRespawn(pSprite)) ? -1 : nDudeToGibClient1;
damageType = DAMAGE_TYPE_3;
if (Chance(0x4000)) {
int top, bottom;
GetSpriteExtents(pSprite, &top, &bottom);
CGibPosition gibPos(pSprite->x, pSprite->y, top);
CGibVelocity gibVel(xvel[pSprite->index] >> 1, yvel[pSprite->index] >> 1, -0xccccc);
GibSprite(pSprite, GIBTYPE_7, &gibPos, &gibVel);
}
GENDUDEEXTRA* pExtra = genDudeExtra(pSprite);
if (pExtra->availDeaths[kDmgBurn] == 3) seqSpawn((15 + Random(2)) + pXSprite->data2, 3, nXSprite, dudeToGib);
else if (pExtra->availDeaths[kDmgBurn] == 2) seqSpawn(16 + pXSprite->data2, 3, nXSprite, dudeToGib);
else if (pExtra->availDeaths[kDmgBurn] == 1) seqSpawn(15 + pXSprite->data2, 3, nXSprite, dudeToGib);
else seqSpawn(1 + pXSprite->data2, 3, nXSprite, dudeToGib);
genDudePostDeath(pSprite, damageType, damage);
return; return;
}
#endif #endif
case kDudeBurningZombieAxe: case kDudeBurningZombieAxe:
if (Chance(0x8000) && nSeq == 3) zombieAxeBurningDeath(actor, nSeq);
sfxPlay3DSound(pSprite, 1109, -1, 0);
else
sfxPlay3DSound(pSprite, 1107+Random(2), -1, 0);
damageType = DAMAGE_TYPE_3; damageType = DAMAGE_TYPE_3;
if (Chance(0x8000))
{
seqSpawn(dudeInfo[nType].seqStartID+13, 3, nXSprite, nDudeToGibClient1);
int top, bottom;
GetSpriteExtents(pSprite, &top, &bottom);
CGibPosition gibPos(pSprite->x, pSprite->y, top);
CGibVelocity gibVel(xvel[pSprite->index]>>1, yvel[pSprite->index]>>1, -0xccccc);
GibSprite(pSprite, GIBTYPE_27, &gibPos, &gibVel);
}
else
seqSpawn(dudeInfo[nType].seqStartID+13, 3, nXSprite, nDudeToGibClient2);
break; break;
case kDudeBurningZombieButcher: case kDudeBurningZombieButcher:
if (Chance(0x4000) && nSeq == 3) genericDeath(actor, nSeq, 1204, dudeInfo[4].seqStartID + 10);
sfxPlay3DSound(pSprite, 1206, -1, 0);
else
sfxPlay3DSound(pSprite, 1204+Random(2), -1, 0);
seqSpawn(dudeInfo[4].seqStartID+10, 3, nXSprite, -1);
break; break;
case kDudeBurningInnocent: case kDudeBurningInnocent:
damageType = DAMAGE_TYPE_3; damageType = DAMAGE_TYPE_3;
seqSpawn(dudeInfo[nType].seqStartID+7, 3, nXSprite, nDudeToGibClient1); seqSpawn(dudeInfo[nType].seqStartID+7, actor, nDudeToGibClient1);
break; break;
case kDudeZombieButcher: case kDudeZombieButcher:
if (nSeq == 14) { zombieButcherDeath(actor, nSeq);
sfxPlay3DSound(pSprite, 1206, -1, 0);
seqSpawn(dudeInfo[nType].seqStartID+11, 3, nXSprite, -1);
break;
}
sfxPlay3DSound(pSprite, 1204+Random(2), -1, 0);
if (nSeq == 3)
seqSpawn(dudeInfo[nType].seqStartID+10, 3, nXSprite, -1);
else
seqSpawn(dudeInfo[nType].seqStartID+nSeq, 3, nXSprite, -1);
break; break;
case kDudeGargoyleFlesh: case kDudeGargoyleFlesh:
if (Chance(0x4000) && nSeq == 3) sfxPlay3DSound(pSprite, 1405, -1, 0); genericDeath(actor, nSeq, 1403, dudeInfo[nType].seqStartID + nSeq);
else sfxPlay3DSound(pSprite, 1403+Random(2), -1, 0);
seqSpawn(dudeInfo[nType].seqStartID+nSeq, 3, nXSprite, -1);
break; break;
case kDudeGargoyleStone: case kDudeGargoyleStone:
if (Chance(0x4000) && nSeq == 3) sfxPlay3DSound(pSprite, 1455, -1, 0); genericDeath(actor, nSeq, 1453, dudeInfo[nType].seqStartID + nSeq);
else sfxPlay3DSound(pSprite, 1453+Random(2), -1, 0);
seqSpawn(dudeInfo[nType].seqStartID+nSeq, 3, nXSprite, -1);
break; break;
case kDudePhantasm: case kDudePhantasm:
if (Chance(0x4000) && nSeq == 3) sfxPlay3DSound(pSprite, 1605, -1, 0); genericDeath(actor, nSeq, 1603, dudeInfo[nType].seqStartID + nSeq);
else sfxPlay3DSound(pSprite, 1603+Random(2), -1, 0);
seqSpawn(dudeInfo[nType].seqStartID+nSeq, 3, nXSprite, -1);
break; break;
case kDudeHellHound: case kDudeHellHound:
if (Chance(0x4000) && nSeq == 3) sfxPlay3DSound(pSprite, 1305, -1, 0); genericDeath(actor, nSeq, 1303, dudeInfo[nType].seqStartID + nSeq);
else sfxPlay3DSound(pSprite, 1303+Random(2), -1, 0);
seqSpawn(dudeInfo[nType].seqStartID+nSeq, 3, nXSprite, -1);
break; break;
case kDudeHand: case kDudeHand:
if (Chance(0x4000) && nSeq == 3) sfxPlay3DSound(pSprite, 1905, -1, 0); genericDeath(actor, nSeq, 1903, dudeInfo[nType].seqStartID + nSeq);
else sfxPlay3DSound(pSprite, 1903+Random(2), -1, 0);
seqSpawn(dudeInfo[nType].seqStartID+nSeq, 3, nXSprite, -1);
break; break;
case kDudeSpiderBrown: case kDudeSpiderBrown:
if (pSprite->owner != -1) { if (pSprite->owner != -1)
{
spritetype *pOwner = &sprite[pSprite->owner]; spritetype *pOwner = &sprite[pSprite->owner];
gDudeExtra[pOwner->extra].at6.u1.xval2--; gDudeExtra[pOwner->extra].at6.u1.xval2--;
} }
genericDeath(actor, nSeq, 1803, dudeInfo[nType].seqStartID + nSeq);
if (Chance(0x4000) && nSeq == 3) sfxPlay3DSound(pSprite, 1805, -1, 0);
else sfxPlay3DSound(pSprite, 1803+Random(2), -1, 0);
seqSpawn(dudeInfo[nType].seqStartID+nSeq, 3, nXSprite, -1);
break; break;
case kDudeSpiderRed: case kDudeSpiderRed:
if (pSprite->owner != -1) { if (pSprite->owner != -1)
{
spritetype *pOwner = &sprite[pSprite->owner]; spritetype *pOwner = &sprite[pSprite->owner];
gDudeExtra[pOwner->extra].at6.u1.xval2--; gDudeExtra[pOwner->extra].at6.u1.xval2--;
} }
genericDeath(actor, nSeq, 1803, dudeInfo[nType].seqStartID + nSeq);
if (Chance(0x4000) && nSeq == 3) sfxPlay3DSound(pSprite, 1805, -1, 0);
else sfxPlay3DSound(pSprite, 1803+Random(2), -1, 0);
seqSpawn(dudeInfo[nType].seqStartID+nSeq, 3, nXSprite, -1);
break; break;
case kDudeSpiderBlack: case kDudeSpiderBlack:
if (pSprite->owner != -1) { if (pSprite->owner != -1)
{
spritetype *pOwner = &sprite[pSprite->owner]; spritetype *pOwner = &sprite[pSprite->owner];
gDudeExtra[pOwner->extra].at6.u1.xval2--; gDudeExtra[pOwner->extra].at6.u1.xval2--;
} }
genericDeath(actor, nSeq, 1803, dudeInfo[nType].seqStartID + nSeq);
if (Chance(0x4000) && nSeq == 3) sfxPlay3DSound(pSprite, 1805, -1, 0);
else sfxPlay3DSound(pSprite, 1803+Random(2), -1, 0);
seqSpawn(dudeInfo[nType].seqStartID+nSeq, 3, nXSprite, -1);
break; break;
case kDudeSpiderMother: case kDudeSpiderMother:
sfxPlay3DSound(pSprite, 1850, -1, 0); sfxPlay3DSound(pSprite, 1850, -1, 0);
seqSpawn(dudeInfo[nType].seqStartID+nSeq, 3, nXSprite, -1); seqSpawn(dudeInfo[nType].seqStartID+nSeq, actor, -1);
break; break;
case kDudeGillBeast: case kDudeGillBeast:
if (Chance(0x4000) && nSeq == 3) sfxPlay3DSound(pSprite, 1705, -1, 0); genericDeath(actor, nSeq, 1703, dudeInfo[nType].seqStartID + nSeq);
else sfxPlay3DSound(pSprite, 1703+Random(2), -1, 0);
seqSpawn(dudeInfo[nType].seqStartID+nSeq, 3, nXSprite, -1);
break; break;
case kDudeBoneEel: case kDudeBoneEel:
if (Chance(0x4000) && nSeq == 3) sfxPlay3DSound(pSprite, 1505, -1, 0); genericDeath(actor, nSeq, 1503, dudeInfo[nType].seqStartID + nSeq);
else sfxPlay3DSound(pSprite, 1503+Random(2), -1, 0);
seqSpawn(dudeInfo[nType].seqStartID+nSeq, 3, nXSprite, -1);
break; break;
case kDudeBat: case kDudeBat:
if (Chance(0x4000) && nSeq == 3) genericDeath(actor, nSeq, 2003, dudeInfo[nType].seqStartID + nSeq);
sfxPlay3DSound(pSprite, 2005, -1, 0);
else
sfxPlay3DSound(pSprite, 2003+Random(2), -1, 0);
seqSpawn(dudeInfo[nType].seqStartID+nSeq, 3, nXSprite, -1);
break; break;
case kDudeRat: case kDudeRat:
if (Chance(0x4000) && nSeq == 3) genericDeath(actor, nSeq, 2103, dudeInfo[nType].seqStartID + nSeq);
sfxPlay3DSound(pSprite, 2105, -1, 0);
else
sfxPlay3DSound(pSprite, 2103+Random(2), -1, 0);
seqSpawn(dudeInfo[nType].seqStartID+nSeq, 3, nXSprite, -1);
break; break;
case kDudePodGreen: case kDudePodGreen:
case kDudeTentacleGreen: case kDudeTentacleGreen:
case kDudePodFire: case kDudePodFire:
case kDudeTentacleFire: case kDudeTentacleFire:
if ((pSprite->cstat & CSTAT_SPRITE_YFLIP)) pSprite->cstat &= ~CSTAT_SPRITE_YFLIP; if ((pSprite->cstat & CSTAT_SPRITE_YFLIP)) pSprite->cstat &= ~CSTAT_SPRITE_YFLIP;
switch (pSprite->type) { switch (pSprite->type)
{
case kDudePodGreen: case kDudePodGreen:
if (Chance(0x4000) && nSeq == 3) genericDeath(actor, nSeq, 2203, dudeInfo[nType].seqStartID + nSeq);
sfxPlay3DSound(pSprite, 2205, -1, 0);
else
sfxPlay3DSound(pSprite, 2203 + Random(2), -1, 0);
seqSpawn(dudeInfo[nType].seqStartID + nSeq, 3, nXSprite, -1);
break; break;
case kDudeTentacleGreen: case kDudeTentacleGreen:
if (damage == 5) sfxPlay3DSound(pSprite, damage == 5 ? 2471 : 2472, -1, 0);
sfxPlay3DSound(pSprite, 2471, -1, 0); seqSpawn(dudeInfo[nType].seqStartID + nSeq, actor, -1);
else
sfxPlay3DSound(pSprite, 2472, -1, 0);
seqSpawn(dudeInfo[nType].seqStartID + nSeq, 3, nXSprite, -1);
break; break;
case kDudePodFire: case kDudePodFire:
if (damage == 5) sfxPlay3DSound(pSprite, damage == 5 ? 2451 : 2452, -1, 0);
sfxPlay3DSound(pSprite, 2451, -1, 0); seqSpawn(dudeInfo[nType].seqStartID + nSeq, actor, -1);
else
sfxPlay3DSound(pSprite, 2452, -1, 0);
seqSpawn(dudeInfo[nType].seqStartID + nSeq, 3, nXSprite, -1);
break; break;
case kDudeTentacleFire: case kDudeTentacleFire:
sfxPlay3DSound(pSprite, 2501, -1, 0); sfxPlay3DSound(pSprite, 2501, -1, 0);
seqSpawn(dudeInfo[nType].seqStartID + nSeq, 3, nXSprite, -1); seqSpawn(dudeInfo[nType].seqStartID + nSeq, actor, -1);
break; break;
} }
break; break;
case kDudePodMother: case kDudePodMother:
if (Chance(0x4000) && nSeq == 3)
sfxPlay3DSound(pSprite, 2205, -1, 0);
else
sfxPlay3DSound(pSprite, 2203+Random(2), -1, 0);
seqSpawn(dudeInfo[nType].seqStartID+nSeq, 3, nXSprite, -1);
break;
case kDudeTentacleMother: case kDudeTentacleMother:
if (Chance(0x4000) && nSeq == 3) genericDeath(actor, nSeq, 2203, dudeInfo[nType].seqStartID + nSeq);
sfxPlay3DSound(pSprite, 2205, -1, 0);
else
sfxPlay3DSound(pSprite, 2203+Random(2), -1, 0);
seqSpawn(dudeInfo[nType].seqStartID+nSeq, 3, nXSprite, -1);
break; break;
case kDudeCerberusTwoHead: case kDudeCerberusTwoHead:
if (Chance(0x4000) && nSeq == 3)
sfxPlay3DSound(pSprite, 2305, -1, 0);
else
sfxPlay3DSound(pSprite, 2305+Random(2), -1, 0);
seqSpawn(dudeInfo[nType].seqStartID+nSeq, 3, nXSprite, -1);
break;
case kDudeCerberusOneHead: case kDudeCerberusOneHead:
if (Chance(0x4000) && nSeq == 3) genericDeath(actor, nSeq, 2303, dudeInfo[nType].seqStartID + nSeq);
sfxPlay3DSound(pSprite, 2305, -1, 0);
else
sfxPlay3DSound(pSprite, 2305+Random(2), -1, 0);
seqSpawn(dudeInfo[nType].seqStartID+nSeq, 3, nXSprite, -1);
break; break;
case kDudeTchernobog: case kDudeTchernobog:
sfxPlay3DSound(pSprite, 2380, -1, 0); sfxPlay3DSound(pSprite, 2380, -1, 0);
seqSpawn(dudeInfo[nType].seqStartID+nSeq, 3, nXSprite, -1); seqSpawn(dudeInfo[nType].seqStartID+nSeq, actor, -1);
break; break;
case kDudeBurningTinyCaleb: case kDudeBurningTinyCaleb:
damageType = DAMAGE_TYPE_3; damageType = DAMAGE_TYPE_3;
seqSpawn(dudeInfo[nType].seqStartID+11, 3, nXSprite, nDudeToGibClient1); seqSpawn(dudeInfo[nType].seqStartID+11, actor, nDudeToGibClient1);
break; break;
case kDudeBeast: case kDudeBeast:
sfxPlay3DSound(pSprite, 9000+Random(2), -1, 0); sfxPlay3DSound(pSprite, 9000+Random(2), -1, 0);
if (nSeq == 3) seqSpawn(dudeInfo[nType].seqStartID+nSeq, actor, nSeq == 3? nDudeToGibClient2 : nDudeToGibClient1);
seqSpawn(dudeInfo[nType].seqStartID+nSeq, 3, nXSprite, nDudeToGibClient2);
else
seqSpawn(dudeInfo[nType].seqStartID+nSeq, 3, nXSprite, nDudeToGibClient1);
break; break;
case kDudeBurningBeast: case kDudeBurningBeast:
damageType = DAMAGE_TYPE_3; damageType = DAMAGE_TYPE_3;
seqSpawn(dudeInfo[nType].seqStartID+12, 3, nXSprite, nDudeToGibClient1); seqSpawn(dudeInfo[nType].seqStartID+12, actor, nDudeToGibClient1);
break; break;
default: default:
seqSpawn(getDudeInfo(nType+kDudeBase)->seqStartID+nSeq, 3, nXSprite, -1); seqSpawn(getDudeInfo(nType+kDudeBase)->seqStartID+nSeq, actor, -1);
break; break;
} }
@ -3524,16 +3649,22 @@ void actKillDude(int nKillerSprite, spritetype *pSprite, DAMAGE_TYPE damageType,
DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type); DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type);
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
if (pDudeInfo->nGibType[i] > -1) if (pDudeInfo->nGibType[i] > -1)
GibSprite(pSprite, (GIBTYPE)pDudeInfo->nGibType[i], NULL, NULL); GibSprite(pSprite, (GIBTYPE)pDudeInfo->nGibType[i], nullptr, nullptr);
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
fxSpawnBlood(pSprite, damage); fxSpawnBlood(pSprite, damage);
} }
gKillMgr.AddKill(pSprite); gKillMgr.AddKill(pSprite);
actCheckRespawn(pSprite); actCheckRespawn(pSprite);
pSprite->type = kThingBloodChunks; pSprite->type = kThingBloodChunks;
actPostSprite(pSprite->index, kStatThing); actPostSprite(actor, kStatThing);
} }
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
int actDamageSprite(int nSource, spritetype *pSprite, DAMAGE_TYPE damageType, int damage) { int actDamageSprite(int nSource, spritetype *pSprite, DAMAGE_TYPE damageType, int damage) {
assert(nSource < kMaxSprites); assert(nSource < kMaxSprites);
@ -7070,5 +7201,10 @@ bool actHealDude(XSPRITE* pXDude, int a2, int a3)
return actHealDude(&bloodActors[pXDude->reference], a2, a3); return actHealDude(&bloodActors[pXDude->reference], a2, a3);
} }
void actKillDude(int a1, spritetype* pSprite, DAMAGE_TYPE a3, int a4)
{
actKillDude(&bloodActors[a1], &bloodActors[pSprite->index], a3, a4);
}
END_BLD_NS END_BLD_NS

View file

@ -217,6 +217,7 @@ void actRadiusDamage(DBloodActor* source, int x, int y, int z, int nSector, int
spritetype *actDropObject(spritetype *pSprite, int nType); spritetype *actDropObject(spritetype *pSprite, int nType);
bool actHealDude(DBloodActor* pXDude, int a2, int a3); bool actHealDude(DBloodActor* pXDude, int a2, int a3);
bool actHealDude(XSPRITE *pXDude, int a2, int a3); bool actHealDude(XSPRITE *pXDude, int a2, int a3);
void actKillDude(DBloodActor* a1, DBloodActor* pSprite, DAMAGE_TYPE a3, int a4);
void actKillDude(int a1, spritetype *pSprite, DAMAGE_TYPE a3, int a4); void actKillDude(int a1, spritetype *pSprite, DAMAGE_TYPE a3, int a4);
int actDamageSprite(int nSource, spritetype *pSprite, DAMAGE_TYPE a3, int a4); 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);

View file

@ -140,4 +140,14 @@ inline void GetActorExtents(DBloodActor* actor, int* top, int* bottom)
GetSpriteExtents(&actor->s(), top, bottom); GetSpriteExtents(&actor->s(), top, bottom);
} }
inline DBloodActor *PLAYER::fragger()
{
return fraggerId == -1? nullptr : &bloodActors[fraggerId];
}
inline void PLAYER::setFragger(DBloodActor* actor)
{
fraggerId = actor == nullptr ? -1 : actor->s().index;
}
END_BLD_NS END_BLD_NS

View file

@ -145,6 +145,8 @@ struct PLAYER
int fragInfo[8]; int fragInfo[8];
int teamId; int teamId;
int fraggerId; int fraggerId;
DBloodActor* fragger();
void setFragger(DBloodActor*);
int underwaterTime; int underwaterTime;
int bubbleTime; int bubbleTime;
int restTime; int restTime;