- Blood: split out the 'modern dude' part of actKillDude.

This commit is contained in:
Christoph Oelckers 2020-12-03 00:00:03 +01:00
parent 34b7bfc10b
commit 9a5a32c826
7 changed files with 142 additions and 97 deletions

View file

@ -2917,47 +2917,48 @@ static DBloodActor* actDropObject(DBloodActor* pSprite, int nType)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool actHealDude(XSPRITE *pXDude, int a2, int a3) bool actHealDude(DBloodActor *actor, int add, int threshold)
{ {
assert(pXDude != NULL); if (!actor) return false;
a2 <<= 4; auto pXDude = &actor->x();
a3 <<= 4; add <<= 4;
if (pXDude->health < a3) threshold <<= 4;
if (pXDude->health < threshold)
{ {
spritetype *pSprite = &sprite[pXDude->reference]; spritetype *pSprite = &actor->s();
if (IsPlayerSprite(pSprite)) if (actor->IsPlayerActor()) sfxPlay3DSound(pSprite->x, pSprite->y, pSprite->z, 780, pSprite->sectnum);
sfxPlay3DSound(pSprite->x, pSprite->y, pSprite->z, 780, pSprite->sectnum); pXDude->health = min<uint32_t>(pXDude->health+add, threshold);
pXDude->health = ClipHigh(pXDude->health+a2, a3); return true;
return 1;
} }
return 0; return false;
} }
void actKillDude(int nKillerSprite, spritetype *pSprite, DAMAGE_TYPE damageType, int damage) //---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
#ifdef NOONE_EXTENSIONS
static bool actKillModernDude(DBloodActor* actor, DAMAGE_TYPE damageType)
{ {
spritetype *pKillerSprite = &sprite[nKillerSprite]; auto pSprite = &actor->s();
assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); auto pXSprite = &actor->x();
int nType = pSprite->type-kDudeBase;
int nXSprite = pSprite->extra;
assert(nXSprite > 0);
XSPRITE *pXSprite = &xsprite[pSprite->extra];
switch (pSprite->type) {
#ifdef NOONE_EXTENSIONS
case kDudeModernCustom: {
GENDUDEEXTRA* pExtra = genDudeExtra(pSprite); GENDUDEEXTRA* pExtra = genDudeExtra(pSprite);
removeDudeStuff(pSprite); removeDudeStuff(pSprite);
if (pXSprite->txID <= 0 || getNextIncarnation(pXSprite) == NULL) { if (pXSprite->txID <= 0 || getNextIncarnation(pXSprite) == NULL)
{
if (pExtra->weaponType == kGenDudeWeaponKamikaze && Chance(0x4000) && damageType != 5 && damageType != 4) { if (pExtra->weaponType == kGenDudeWeaponKamikaze && Chance(0x4000) && damageType != DAMAGE_TYPE_5 && damageType != DAMAGE_TYPE_4)
{
doExplosion(pSprite, pXSprite->data1 - kTrapExploder); doExplosion(pSprite, pXSprite->data1 - kTrapExploder);
if (Chance(0x9000)) damageType = (DAMAGE_TYPE) 3; if (Chance(0x9000)) damageType = (DAMAGE_TYPE)3;
} }
if (damageType == DAMAGE_TYPE_1) { if (damageType == DAMAGE_TYPE_1)
if (pExtra->availDeaths[DAMAGE_TYPE_1] && !spriteIsUnderwater(pSprite)) { {
if (pExtra->canBurn) { if (pExtra->availDeaths[DAMAGE_TYPE_1] && !spriteIsUnderwater(pSprite))
{
if (pExtra->canBurn)
{
pSprite->type = kDudeModernCustomBurning; pSprite->type = kDudeModernCustomBurning;
if (pXSprite->data2 == kGenDudeDefaultSeq) // don't inherit palette for burning if using default animation if (pXSprite->data2 == kGenDudeDefaultSeq) // don't inherit palette for burning if using default animation
pSprite->pal = 0; pSprite->pal = 0;
@ -2966,18 +2967,20 @@ void actKillDude(int nKillerSprite, spritetype *pSprite, DAMAGE_TYPE damageType,
actHealDude(pXSprite, dudeInfo[55].startHealth, dudeInfo[55].startHealth); actHealDude(pXSprite, dudeInfo[55].startHealth, dudeInfo[55].startHealth);
if (pXSprite->burnTime <= 0) pXSprite->burnTime = 1200; if (pXSprite->burnTime <= 0) pXSprite->burnTime = 1200;
gDudeExtra[pSprite->extra].time = PlayClock + 360; gDudeExtra[pSprite->extra].time = PlayClock + 360;
return; return true;
} }
} else { }
else
{
pXSprite->burnTime = 0; pXSprite->burnTime = 0;
pXSprite->burnSource = -1; pXSprite->burnSource = -1;
damageType = DAMAGE_TYPE_0; damageType = DAMAGE_TYPE_0;
} }
} }
}
} else { else
{
pXSprite->locked = 1; // lock while transforming pXSprite->locked = 1; // lock while transforming
aiSetGenIdleState(pSprite, pXSprite); // set idle state aiSetGenIdleState(pSprite, pXSprite); // set idle state
@ -2988,16 +2991,18 @@ void actKillDude(int nKillerSprite, spritetype *pSprite, DAMAGE_TYPE damageType,
if (pXSprite->dropMsg > 0) // drop items if (pXSprite->dropMsg > 0) // drop items
actDropObject(pSprite, pXSprite->dropMsg); actDropObject(pSprite, pXSprite->dropMsg);
pSprite->flags &= ~kPhysMove; xvel[pSprite->index] = yvel[pSprite->index] = 0; pSprite->flags &= ~kPhysMove; xvel[pSprite->index] = yvel[pSprite->index] = 0;
playGenDudeSound(pSprite, kGenDudeSndTransforming); playGenDudeSound(pSprite, kGenDudeSndTransforming);
int seqId = pXSprite->data2 + kGenDudeSeqTransform; int seqId = pXSprite->data2 + kGenDudeSeqTransform;
if (getSequence(seqId)) seqSpawn(seqId, 3, nXSprite, -1); if (getSequence(seqId)) seqSpawn(seqId, actor, -1);
else { else
seqKill(3, nXSprite); {
spritetype* pEffect = gFX.fxSpawn((FX_ID)52, pSprite->sectnum, pSprite->x, pSprite->y, pSprite->z, pSprite->ang); seqKill(actor);
if (pEffect != NULL) { DBloodActor* pEffectA = gFX.fxSpawnActor((FX_ID)52, pSprite->sectnum, pSprite->x, pSprite->y, pSprite->z, pSprite->ang);
if (pEffectA != nullptr)
{
auto pEffect = &pEffectA->s();
pEffect->cstat = CSTAT_SPRITE_ALIGNMENT_FACING; pEffect->cstat = CSTAT_SPRITE_ALIGNMENT_FACING;
pEffect->pal = 6; pEffect->pal = 6;
pEffect->xrepeat = pSprite->xrepeat; pEffect->xrepeat = pSprite->xrepeat;
@ -3005,24 +3010,43 @@ void actKillDude(int nKillerSprite, spritetype *pSprite, DAMAGE_TYPE damageType,
} }
GIBTYPE nGibType; GIBTYPE nGibType;
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++)
{
if (Chance(0x3000)) nGibType = GIBTYPE_6; if (Chance(0x3000)) nGibType = GIBTYPE_6;
else if (Chance(0x2000)) nGibType = GIBTYPE_5; else if (Chance(0x2000)) nGibType = GIBTYPE_5;
else nGibType = GIBTYPE_17; else nGibType = GIBTYPE_17;
int top, bottom; int top, bottom;
GetSpriteExtents(pSprite, &top, &bottom); GetActorExtents(actor, &top, &bottom);
CGibPosition gibPos(pSprite->x, pSprite->y, top); CGibPosition gibPos(pSprite->x, pSprite->y, top);
CGibVelocity gibVel(xvel[pSprite->index] >> 1, yvel[pSprite->index] >> 1, -0xccccc); CGibVelocity gibVel(actor->xvel() >> 1, actor->yvel() >> 1, -0xccccc);
GibSprite(pSprite, nGibType, &gibPos, &gibVel); GibSprite(pSprite, nGibType, &gibPos, &gibVel);
} }
} }
pXSprite->sysData1 = kGenDudeTransformStatus; // in transform pXSprite->sysData1 = kGenDudeTransformStatus; // in transform
return; return true;
} }
return false;
}
#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];
switch (pSprite->type)
{
#ifdef NOONE_EXTENSIONS
case kDudeModernCustom:
if (actKillModernDude(actor, damageType)) return;
break; break;
}
#endif #endif
case kDudeCerberusTwoHead: // Cerberus case kDudeCerberusTwoHead: // Cerberus
seqSpawn(dudeInfo[nType].seqStartID+1, 3, nXSprite, -1); seqSpawn(dudeInfo[nType].seqStartID+1, 3, nXSprite, -1);
@ -3034,8 +3058,8 @@ void actKillDude(int nKillerSprite, spritetype *pSprite, DAMAGE_TYPE damageType,
if (damageType == DAMAGE_TYPE_1 && pXSprite->medium == kMediumNormal) if (damageType == DAMAGE_TYPE_1 && pXSprite->medium == kMediumNormal)
{ {
pSprite->type = kDudeBurningCultist; pSprite->type = kDudeBurningCultist;
aiNewState(&bloodActors[pXSprite->reference], &cultistBurnGoto); aiNewState(actor, &cultistBurnGoto);
actHealDude(pXSprite, dudeInfo[40].startHealth, dudeInfo[40].startHealth); actHealDude(actor, dudeInfo[40].startHealth, dudeInfo[40].startHealth);
return; return;
} }
// no break // no break
@ -3044,8 +3068,8 @@ void actKillDude(int nKillerSprite, spritetype *pSprite, DAMAGE_TYPE damageType,
if (damageType == DAMAGE_TYPE_1 && pXSprite->medium == kMediumNormal) if (damageType == DAMAGE_TYPE_1 && pXSprite->medium == kMediumNormal)
{ {
pSprite->type = kDudeBurningBeast; pSprite->type = kDudeBurningBeast;
aiNewState(&bloodActors[pXSprite->reference], &beastBurnGoto); aiNewState(actor, &beastBurnGoto);
actHealDude(pXSprite, dudeInfo[53].startHealth, dudeInfo[53].startHealth); actHealDude(actor, dudeInfo[53].startHealth, dudeInfo[53].startHealth);
return; return;
} }
// no break // no break
@ -3054,8 +3078,8 @@ void actKillDude(int nKillerSprite, spritetype *pSprite, DAMAGE_TYPE damageType,
if (damageType == DAMAGE_TYPE_1 && pXSprite->medium == kMediumNormal) if (damageType == DAMAGE_TYPE_1 && pXSprite->medium == kMediumNormal)
{ {
pSprite->type = kDudeBurningInnocent; pSprite->type = kDudeBurningInnocent;
aiNewState(&bloodActors[pXSprite->reference], &innocentBurnGoto); aiNewState(actor, &innocentBurnGoto);
actHealDude(pXSprite, dudeInfo[39].startHealth, dudeInfo[39].startHealth); actHealDude(actor, dudeInfo[39].startHealth, dudeInfo[39].startHealth);
return; return;
} }
break; break;
@ -7041,5 +7065,10 @@ spritetype* actDropObject(spritetype* pSprite, int nType)
return act ? &act->s() : nullptr; return act ? &act->s() : nullptr;
} }
bool actHealDude(XSPRITE* pXDude, int a2, int a3)
{
return actHealDude(&bloodActors[pXDude->reference], a2, a3);
}
END_BLD_NS END_BLD_NS

View file

@ -215,6 +215,7 @@ int actWallBounceVector(int *x, int *y, int nWall, int a4);
int actFloorBounceVector(int *x, int *y, int *z, int nSector, int a5); int actFloorBounceVector(int *x, int *y, int *z, int nSector, int a5);
void actRadiusDamage(DBloodActor* source, int x, int y, int z, int nSector, int nDist, int a7, int a8, DAMAGE_TYPE a9, int a10, int a11); void actRadiusDamage(DBloodActor* source, int x, int y, int z, int nSector, int nDist, int a7, int a8, DAMAGE_TYPE a9, int a10, int a11);
spritetype *actDropObject(spritetype *pSprite, int nType); spritetype *actDropObject(spritetype *pSprite, int nType);
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(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);

View file

@ -140,5 +140,4 @@ inline void GetActorExtents(DBloodActor* actor, int* top, int* bottom)
GetSpriteExtents(&actor->s(), top, bottom); GetSpriteExtents(&actor->s(), top, bottom);
} }
END_BLD_NS END_BLD_NS

View file

@ -25,6 +25,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "build.h" #include "build.h"
#include "blood.h" #include "blood.h"
#include "bloodactor.h"
BEGIN_BLD_NS BEGIN_BLD_NS
@ -353,4 +354,11 @@ void fxPrecache()
} }
} }
DBloodActor* CFX::fxSpawnActor(FX_ID nFx, int nSector, int x, int y, int z, unsigned int a6)
{
auto spr = fxSpawn(nFx, nSector, x, y, z, a6);
return spr ? &bloodActors[spr->index] : nullptr;
}
END_BLD_NS END_BLD_NS

View file

@ -94,6 +94,7 @@ public:
void destroy(int); void destroy(int);
void remove(int); void remove(int);
spritetype * fxSpawn(FX_ID, int, int, int, int, unsigned int); spritetype * fxSpawn(FX_ID, int, int, int, int, unsigned int);
DBloodActor* fxSpawnActor(FX_ID, int, int, int, int, unsigned int);
void fxProcess(void); void fxProcess(void);
}; };

View file

@ -487,6 +487,12 @@ void seqKillAll()
activeList.clear(); activeList.clear();
} }
void seqKill(DBloodActor* actor)
{
activeList.remove(4, actor->s().extra);
}
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// //
// //

View file

@ -103,6 +103,7 @@ void seqSpawn(int a1, int a2, int a3, int a4 = -1);
void seqSpawn(int a1, DBloodActor* actor, int a4 = -1); void seqSpawn(int a1, DBloodActor* actor, int a4 = -1);
void seqKill(int a1, int a2); void seqKill(int a1, int a2);
void seqKill(DBloodActor* actor);
void seqKillAll(void); void seqKillAll(void);
int seqGetStatus(int a1, int a2); int seqGetStatus(int a1, int a2);
int seqGetID(int a1, int a2); int seqGetID(int a1, int a2);