Add bumper explosion effect

This commit is contained in:
Sally Coolatta 2020-11-15 12:56:03 -05:00
parent 827a1b5fca
commit 42f411399a
6 changed files with 190 additions and 33 deletions

View file

@ -8720,6 +8720,30 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_BATTLEBUMPER2", "S_BATTLEBUMPER2",
"S_BATTLEBUMPER3", "S_BATTLEBUMPER3",
"S_BATTLEBUMPER_EXCRYSTALA1",
"S_BATTLEBUMPER_EXCRYSTALA2",
"S_BATTLEBUMPER_EXCRYSTALA3",
"S_BATTLEBUMPER_EXCRYSTALA4",
"S_BATTLEBUMPER_EXCRYSTALB1",
"S_BATTLEBUMPER_EXCRYSTALB2",
"S_BATTLEBUMPER_EXCRYSTALB3",
"S_BATTLEBUMPER_EXCRYSTALB4",
"S_BATTLEBUMPER_EXCRYSTALC1",
"S_BATTLEBUMPER_EXCRYSTALC2",
"S_BATTLEBUMPER_EXCRYSTALC3",
"S_BATTLEBUMPER_EXCRYSTALC4",
"S_BATTLEBUMPER_EXSHELLA1",
"S_BATTLEBUMPER_EXSHELLA2",
"S_BATTLEBUMPER_EXSHELLB1",
"S_BATTLEBUMPER_EXSHELLB2",
"S_BATTLEBUMPER_EXSHELLC1",
"S_BATTLEBUMPER_EXSHELLC2",
// DEZ respawn laser // DEZ respawn laser
"S_DEZLASER", "S_DEZLASER",
"S_DEZLASER_TRAIL1", "S_DEZLASER_TRAIL1",

View file

@ -563,6 +563,8 @@ char sprnames[NUMSPRITES + 1][5] =
"SINK", // Kitchen Sink "SINK", // Kitchen Sink
"SITR", // Kitchen Sink Trail "SITR", // Kitchen Sink Trail
"KBLN", // Battle Mode Bumper "KBLN", // Battle Mode Bumper
"BEXC", // Battle Bumper Explosion: Crystal
"BEXS", // Battle Bumper Explosion: Shell
"DEZL", // DEZ Laser respawn "DEZL", // DEZ Laser respawn
@ -4402,9 +4404,33 @@ state_t states[NUMSTATES] =
{SPR_SITR, 1, 5, {NULL}, 0, 0, S_SINKTRAIL3}, // S_SINKTRAIL2 {SPR_SITR, 1, 5, {NULL}, 0, 0, S_SINKTRAIL3}, // S_SINKTRAIL2
{SPR_SITR, 2, 3, {NULL}, 0, 0, S_NULL}, // S_SINKTRAIL3 {SPR_SITR, 2, 3, {NULL}, 0, 0, S_NULL}, // S_SINKTRAIL3
{SPR_KBLN, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_BATTLEBUMPER1}, // S_BATTLEBUMPER1 {SPR_KBLN, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_BATTLEBUMPER1
{SPR_KBLN, FF_FULLBRIGHT|1, -1, {NULL}, 0, 0, S_BATTLEBUMPER2}, // S_BATTLEBUMPER2 {SPR_KBLN, FF_FULLBRIGHT|1, -1, {NULL}, 0, 0, S_NULL}, // S_BATTLEBUMPER2
{SPR_KBLN, FF_FULLBRIGHT|2, -1, {NULL}, 0, 0, S_BATTLEBUMPER3}, // S_BATTLEBUMPER3 {SPR_KBLN, FF_FULLBRIGHT|2, -1, {NULL}, 0, 0, S_NULL}, // S_BATTLEBUMPER3
{SPR_BEXC, FF_SEMIBRIGHT, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALA2}, // S_BATTLEBUMPER_EXCRYSTALA1
{SPR_BEXC, FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALA3}, // S_BATTLEBUMPER_EXCRYSTALA2
{SPR_BEXC, FF_SEMIBRIGHT, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALA4}, // S_BATTLEBUMPER_EXCRYSTALA3
{SPR_BEXC, FF_FULLBRIGHT|2, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALA1}, // S_BATTLEBUMPER_EXCRYSTALA4
{SPR_BEXC, FF_SEMIBRIGHT|3, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALB2}, // S_BATTLEBUMPER_EXCRYSTALB1
{SPR_BEXC, FF_FULLBRIGHT|4, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALB3}, // S_BATTLEBUMPER_EXCRYSTALB2
{SPR_BEXC, FF_SEMIBRIGHT|3, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALB4}, // S_BATTLEBUMPER_EXCRYSTALB3
{SPR_BEXC, FF_FULLBRIGHT|5, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALB1}, // S_BATTLEBUMPER_EXCRYSTALB4
{SPR_BEXC, FF_SEMIBRIGHT|6, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALC2}, // S_BATTLEBUMPER_EXCRYSTALC1
{SPR_BEXC, FF_FULLBRIGHT|7, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALC3}, // S_BATTLEBUMPER_EXCRYSTALC2
{SPR_BEXC, FF_SEMIBRIGHT|6, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALC4}, // S_BATTLEBUMPER_EXCRYSTALC3
{SPR_BEXC, FF_FULLBRIGHT|8, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALC1}, // S_BATTLEBUMPER_EXCRYSTALC4
{SPR_BEXS, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXSHELLA2}, // S_BATTLEBUMPER_EXSHELLA1
{SPR_BEXS, FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXSHELLA1}, // S_BATTLEBUMPER_EXSHELLA2
{SPR_BEXS, FF_FULLBRIGHT|2, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXSHELLB2}, // S_BATTLEBUMPER_EXSHELLB1
{SPR_BEXS, FF_FULLBRIGHT|3, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXSHELLB1}, // S_BATTLEBUMPER_EXSHELLB2
{SPR_BEXS, FF_FULLBRIGHT|4, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXSHELLC2}, // S_BATTLEBUMPER_EXSHELLC1
{SPR_BEXS, FF_FULLBRIGHT|5, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXSHELLC1}, // S_BATTLEBUMPER_EXSHELLC2
{SPR_DEZL, FF_FULLBRIGHT|FF_PAPERSPRITE, 8, {NULL}, 0, 0, S_NULL}, // S_DEZLASER {SPR_DEZL, FF_FULLBRIGHT|FF_PAPERSPRITE, 8, {NULL}, 0, 0, S_NULL}, // S_DEZLASER
{SPR_DEZL, FF_FULLBRIGHT|1, 2, {NULL}, 0, 0, S_DEZLASER_TRAIL2}, // S_DEZLASER_TRAIL1 {SPR_DEZL, FF_FULLBRIGHT|1, 2, {NULL}, 0, 0, S_DEZLASER_TRAIL2}, // S_DEZLASER_TRAIL1
@ -24061,7 +24087,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
sfx_None, // painsound sfx_None, // painsound
S_NULL, // meleestate S_NULL, // meleestate
S_NULL, // missilestate S_NULL, // missilestate
S_NULL, // deathstate S_BATTLEBUMPER_EXCRYSTALA1, // deathstate
S_NULL, // xdeathstate S_NULL, // xdeathstate
sfx_None, // deathsound sfx_None, // deathsound
4*FRACUNIT, // speed 4*FRACUNIT, // speed

View file

@ -834,6 +834,8 @@ typedef enum sprite
SPR_SINK, // Kitchen Sink SPR_SINK, // Kitchen Sink
SPR_SITR, // Kitchen Sink Trail SPR_SITR, // Kitchen Sink Trail
SPR_KBLN, // Battle Mode Bumper SPR_KBLN, // Battle Mode Bumper
SPR_BEXC, // Battle Bumper Explosion: Crystal
SPR_BEXS, // Battle Bumper Explosion: Shell
SPR_DEZL, // DEZ Laser respawn SPR_DEZL, // DEZ Laser respawn
@ -4571,6 +4573,30 @@ typedef enum state
S_BATTLEBUMPER2, S_BATTLEBUMPER2,
S_BATTLEBUMPER3, S_BATTLEBUMPER3,
S_BATTLEBUMPER_EXCRYSTALA1,
S_BATTLEBUMPER_EXCRYSTALA2,
S_BATTLEBUMPER_EXCRYSTALA3,
S_BATTLEBUMPER_EXCRYSTALA4,
S_BATTLEBUMPER_EXCRYSTALB1,
S_BATTLEBUMPER_EXCRYSTALB2,
S_BATTLEBUMPER_EXCRYSTALB3,
S_BATTLEBUMPER_EXCRYSTALB4,
S_BATTLEBUMPER_EXCRYSTALC1,
S_BATTLEBUMPER_EXCRYSTALC2,
S_BATTLEBUMPER_EXCRYSTALC3,
S_BATTLEBUMPER_EXCRYSTALC4,
S_BATTLEBUMPER_EXSHELLA1,
S_BATTLEBUMPER_EXSHELLA2,
S_BATTLEBUMPER_EXSHELLB1,
S_BATTLEBUMPER_EXSHELLB2,
S_BATTLEBUMPER_EXSHELLC1,
S_BATTLEBUMPER_EXSHELLC2,
// DEZ Laser respawn // DEZ Laser respawn
S_DEZLASER, S_DEZLASER,
S_DEZLASER_TRAIL1, S_DEZLASER_TRAIL1,

View file

@ -2679,10 +2679,6 @@ void K_DestroyBumpers(player_t *player, UINT8 amount)
} }
player->bumpers -= amount; player->bumpers -= amount;
// TODO: Store a bumperlist on the player mobj,
// that way we can do a bumper destruction animation
K_HandleBumperChanges(player, oldBumpers); K_HandleBumperChanges(player, oldBumpers);
} }

View file

@ -1065,12 +1065,6 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
{ {
mobj_t *mo; mobj_t *mo;
//if (inflictor && (inflictor->type == MT_SHELL || inflictor->type == MT_FIREBALL))
// P_SetTarget(&target->tracer, inflictor);
if (G_IsSpecialStage(gamemap) && target->player && target->player->nightstime > 6)
target->player->nightstime = 6; // Just let P_Ticker take care of the rest.
if (target->flags & (MF_ENEMY|MF_BOSS)) if (target->flags & (MF_ENEMY|MF_BOSS))
target->momx = target->momy = target->momz = 0; target->momx = target->momy = target->momz = 0;
@ -1096,7 +1090,11 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
target->flags &= ~(MF_SHOOTABLE|MF_FLOAT|MF_SPECIAL); target->flags &= ~(MF_SHOOTABLE|MF_FLOAT|MF_SPECIAL);
target->flags2 &= ~(MF2_SKULLFLY|MF2_NIGHTSPULL); target->flags2 &= ~(MF2_SKULLFLY|MF2_NIGHTSPULL);
target->health = 0; // This makes it easy to check if something's dead elsewhere. target->health = 0; // This makes it easy to check if something's dead elsewhere.
target->shadowscale = 0;
if (target->type != MT_BATTLEBUMPER)
{
target->shadowscale = 0;
}
if (LUAh_MobjDeath(target, inflictor, source, damagetype) || P_MobjWasRemoved(target)) if (LUAh_MobjDeath(target, inflictor, source, damagetype) || P_MobjWasRemoved(target))
return; return;
@ -1219,7 +1217,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
} }
} }
if ((gametyperules & GTR_BUMPERS)) if (gametyperules & GTR_BUMPERS)
K_CheckBumpers(); K_CheckBumpers();
target->player->kartstuff[k_pogospring] = 0; target->player->kartstuff[k_pogospring] = 0;
@ -1449,6 +1447,42 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
} }
break; break;
case MT_BATTLEBUMPER:
{
mobj_t *owner = target->target;
mobj_t *overlay;
target->flags &= ~MF_NOGRAVITY;
target->destscale = (3 * target->destscale) / 2;
target->scalespeed = FRACUNIT/100;
if (owner && !P_MobjWasRemoved(owner))
{
/*
target->momx = owner->momx / 2;
target->momy = owner->momy / 2;
target->momz = owner->momz / 2;
*/
P_Thrust(target, R_PointToAngle2(owner->x, owner->y, target->x, target->y), 4 * target->scale);
}
target->momz += (24 * target->scale) * P_MobjFlip(target);
target->shadowscale *= 3;
target->fuse = 16;
overlay = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_OVERLAY);
P_SetTarget(&target->tracer, overlay);
P_SetTarget(&overlay->target, target);
overlay->color = target->color;
P_SetMobjState(overlay, S_BATTLEBUMPER_EXSHELLA1);
}
break;
default: default:
break; break;
} }
@ -1685,11 +1719,12 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source,
return false; return false;
} }
K_DestroyBumpers(player, 1);
switch (type) switch (type)
{ {
case DMG_DEATHPIT: case DMG_DEATHPIT:
// Respawn kill types // Respawn kill types
K_DestroyBumpers(player, 1);
K_DoIngameRespawn(player); K_DoIngameRespawn(player);
return false; return false;
default: default:

View file

@ -1157,6 +1157,7 @@ fixed_t P_GetMobjGravity(mobj_t *mo)
break; break;
case MT_WATERDROP: case MT_WATERDROP:
case MT_CYBRAKDEMON: case MT_CYBRAKDEMON:
case MT_BATTLEBUMPER:
gravityadd /= 2; gravityadd /= 2;
break; break;
case MT_BANANA: case MT_BANANA:
@ -1165,7 +1166,10 @@ fixed_t P_GetMobjGravity(mobj_t *mo)
case MT_SINK: case MT_SINK:
case MT_EMERALD: case MT_EMERALD:
if (mo->extravalue2 > 0) if (mo->extravalue2 > 0)
{
gravityadd *= mo->extravalue2; gravityadd *= mo->extravalue2;
}
gravityadd = (5*gravityadd)/2; gravityadd = (5*gravityadd)/2;
break; break;
case MT_KARMAFIREWORK: case MT_KARMAFIREWORK:
@ -5280,15 +5284,52 @@ static void P_MobjSceneryThink(mobj_t *mobj)
case MT_BATTLEBUMPER: case MT_BATTLEBUMPER:
if (mobj->health <= 0) if (mobj->health <= 0)
{ {
// DO EXPLODE ANIMATION HERE mobj->fuse--;
//CONS_Printf("bumper explosion\n");
P_RemoveMobj(mobj);
return;
}
else if (mobj->target && mobj->target->player && mobj->target->health > 0 && !mobj->target->player->spectator)
{
// Following a player
if (mobj->fuse <= 0)
{
statenum_t curState = (mobj->state - states);
if (curState >= S_BATTLEBUMPER_EXCRYSTALA1 && curState <= S_BATTLEBUMPER_EXCRYSTALA4)
{
P_SetMobjState(mobj, S_BATTLEBUMPER_EXCRYSTALB1);
if (mobj->tracer && !P_MobjWasRemoved(mobj->tracer))
{
P_SetMobjState(mobj->tracer, S_BATTLEBUMPER_EXSHELLB1);
}
mobj->shadowscale *= 3;
mobj->fuse = 24;
break;
}
else if (curState >= S_BATTLEBUMPER_EXCRYSTALB1 && curState <= S_BATTLEBUMPER_EXCRYSTALB4)
{
P_SetMobjState(mobj, S_BATTLEBUMPER_EXCRYSTALC1);
if (mobj->tracer && !P_MobjWasRemoved(mobj->tracer))
{
P_SetMobjState(mobj->tracer, S_BATTLEBUMPER_EXSHELLC1);
}
mobj->shadowscale *= 3;
mobj->fuse = 32;
break;
}
else
{
// TODO: confetti goes here
P_RemoveMobj(mobj);
return;
}
}
break;
}
if (mobj->target && !P_MobjWasRemoved(mobj->target) && mobj->target->player
&& mobj->target->health > 0 && !mobj->target->player->spectator)
{
fixed_t rad = 32*mobj->target->scale; fixed_t rad = 32*mobj->target->scale;
fixed_t offz; fixed_t offz;
angle_t ang, diff; angle_t ang, diff;
@ -5320,15 +5361,23 @@ static void P_MobjSceneryThink(mobj_t *mobj)
mobj->drawflags = (mobj->target->drawflags & MFD_DONTDRAW); mobj->drawflags = (mobj->target->drawflags & MFD_DONTDRAW);
if (mobj->target->eflags & MFE_VERTICALFLIP) if (mobj->target->eflags & MFE_VERTICALFLIP)
{
offz += 4*FRACUNIT; offz += 4*FRACUNIT;
}
else else
{
offz -= 4*FRACUNIT; offz -= 4*FRACUNIT;
}
if (mobj->tracer && mobj->tracer->player && mobj->tracer->player->mo if (mobj->tracer && !P_MobjWasRemoved(mobj->tracer) && mobj->tracer->player
&& mobj->tracer->health > 0 && !mobj->tracer->player->spectator) // STOLEN && mobj->tracer->health > 0 && !mobj->tracer->player->spectator) // STOLEN
mobj->color = mobj->tracer->player->skincolor; // don't do star flashing for stolen bumpers {
mobj->color = mobj->tracer->color;
}
else else
mobj->color = mobj->target->color; // but do so if it belongs to you :B {
mobj->color = mobj->target->color;
}
if (mobj->target->player->bumpers < 2) if (mobj->target->player->bumpers < 2)
P_SetMobjState(mobj, S_BATTLEBUMPER3); P_SetMobjState(mobj, S_BATTLEBUMPER3);
@ -5338,11 +5387,11 @@ static void P_MobjSceneryThink(mobj_t *mobj)
P_SetMobjState(mobj, S_BATTLEBUMPER1); P_SetMobjState(mobj, S_BATTLEBUMPER1);
// Shrink your items if the player shrunk too. // Shrink your items if the player shrunk too.
mobj->scale = mobj->target->scale; P_SetScale(mobj, mobj->target->scale);
P_UnsetThingPosition(mobj); P_UnsetThingPosition(mobj);
{ {
const angle_t fa = ang>>ANGLETOFINESHIFT; const angle_t fa = ang >> ANGLETOFINESHIFT;
mobj->x = mobj->target->x + FixedMul(FINECOSINE(fa), rad); mobj->x = mobj->target->x + FixedMul(FINECOSINE(fa), rad);
mobj->y = mobj->target->y + FixedMul(FINESINE(fa), rad); mobj->y = mobj->target->y + FixedMul(FINESINE(fa), rad);
mobj->z = mobj->target->z + offz; mobj->z = mobj->target->z + offz;
@ -5351,9 +5400,9 @@ static void P_MobjSceneryThink(mobj_t *mobj)
if (mobj->target->player->bumpers <= mobj->threshold) if (mobj->target->player->bumpers <= mobj->threshold)
{ {
// Sliently remove // Do bumper destruction
P_RemoveMobj(mobj); P_KillMobj(mobj, NULL, NULL, DMG_NORMAL);
return; break;
} }
} }
else else
@ -8366,6 +8415,7 @@ static boolean P_FuseThink(mobj_t *mobj)
if (mobj->threshold == 70) if (mobj->threshold == 70)
newmobj->threshold = 70; newmobj->threshold = 70;
} }
P_RemoveMobj(mobj); // make sure they disappear P_RemoveMobj(mobj); // make sure they disappear
return false; return false;
case MT_SMK_ICEBLOCK: case MT_SMK_ICEBLOCK: