Merge branch 'user-defined-death-kart-frame' into 'master'

SPR2_DKRT: A new SPR2 which allows character WADs to define a unique kart explosion husk

See merge request KartKrew/RingRacers!55
This commit is contained in:
Sal 2024-10-21 23:59:21 +00:00
commit dd45f3cd61
5 changed files with 33 additions and 6 deletions

View file

@ -369,6 +369,7 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
"S_KART_LEFTOVER", "S_KART_LEFTOVER",
"S_KART_LEFTOVER_NOTIRES", "S_KART_LEFTOVER_NOTIRES",
"S_KART_LEFTOVER_CUSTOM",
"S_KART_TIRE1", "S_KART_TIRE1",
"S_KART_TIRE2", "S_KART_TIRE2",

View file

@ -795,6 +795,7 @@ char spr2names[NUMPLAYERSPRITES][5] =
"SIGN", "SIGL", "SSIG", // Finish signpost "SIGN", "SIGL", "SSIG", // Finish signpost
"XTRA", // Three Faces of Darkness "XTRA", // Three Faces of Darkness
"TALK", // Dialogue "TALK", // Dialogue
"DKRT", // Kart husk
}; };
playersprite_t free_spr2 = SPR2_FIRSTFREESLOT; playersprite_t free_spr2 = SPR2_FIRSTFREESLOT;
@ -839,13 +840,14 @@ playersprite_t spr2defaults[NUMPLAYERSPRITES] = {
SPR2_SIGN, // SPR2_SSIG SPR2_SIGN, // SPR2_SSIG
0, // SPR2_XTRA 0, // SPR2_XTRA
0, // SPR2_TALK 0, // SPR2_TALK
0, // SPR2_DKRT
}; };
// Doesn't work with g++, needs actionf_p1 (don't modify this comment) // Doesn't work with g++, needs actionf_p1 (don't modify this comment)
state_t states[NUMSTATES] = state_t states[NUMSTATES] =
{ {
// frame is masked through FF_FRAMEMASK // frame is masked through FF_FRAMEMASK
// FF_ANIMATE makes simple state animations (var1 #frames, var2 tic delay) // FF_ANIMATE makes simple state animations (var1 #frames, var2 tic delay) (var1 is ignored in P_SetupStateAnimation() if sprite is SPR_PLAY)
// FF_FULLBRIGHT activates the fullbright colormap // FF_FULLBRIGHT activates the fullbright colormap
// use FF_TRANS10 - FF_TRANS90 for easy translucency // use FF_TRANS10 - FF_TRANS90 for easy translucency
// (or tr_trans10<<FF_TRANSSHIFT if you want to make it hard on yourself) // (or tr_trans10<<FF_TRANSSHIFT if you want to make it hard on yourself)
@ -903,6 +905,7 @@ state_t states[NUMSTATES] =
{SPR_KART, 0, -1, {NULL}, 0, 0, S_NULL}, // S_KART_LEFTOVER {SPR_KART, 0, -1, {NULL}, 0, 0, S_NULL}, // S_KART_LEFTOVER
{SPR_DIEF, 0, -1, {NULL}, 0, 0, S_NULL}, // S_KART_LEFTOVER_NOTIRES {SPR_DIEF, 0, -1, {NULL}, 0, 0, S_NULL}, // S_KART_LEFTOVER_NOTIRES
{SPR_PLAY, SPR2_DKRT,3,{NULL},0,0,S_KART_LEFTOVER_CUSTOM},// S_KART_LEFTOVER_CUSTOM
{SPR_TIRE, 0, -1, {NULL}, 0, 0, S_NULL}, // S_KART_TIRE1 {SPR_TIRE, 0, -1, {NULL}, 0, 0, S_NULL}, // S_KART_TIRE1
{SPR_TIRE, 1, -1, {NULL}, 0, 0, S_NULL}, // S_KART_TIRE2 {SPR_TIRE, 1, -1, {NULL}, 0, 0, S_NULL}, // S_KART_TIRE2

View file

@ -1329,6 +1329,7 @@ typedef enum playersprite
SPR2_SIGN, SPR2_SIGL, SPR2_SSIG, SPR2_SIGN, SPR2_SIGL, SPR2_SSIG,
SPR2_XTRA, SPR2_XTRA,
SPR2_TALK, SPR2_TALK,
SPR2_DKRT,
SPR2_FIRSTFREESLOT, SPR2_FIRSTFREESLOT,
SPR2_LASTFREESLOT = 0x7f, SPR2_LASTFREESLOT = 0x7f,
@ -1389,6 +1390,7 @@ typedef enum state
S_KART_LEFTOVER, S_KART_LEFTOVER,
S_KART_LEFTOVER_NOTIRES, S_KART_LEFTOVER_NOTIRES,
S_KART_LEFTOVER_CUSTOM,
S_KART_TIRE1, S_KART_TIRE1,
S_KART_TIRE2, S_KART_TIRE2,

View file

@ -309,15 +309,34 @@ struct Kart : Mobj
return true; return true;
} }
if (health <= 1) if (health <= 1)
{ {
return false; return false;
} }
Mobj* p = player();
bool pValid = Mobj::valid(p) && p->player;
bool hasCustomHusk = pValid && skins[p->player->skin].sprites[SPR2_DKRT].numframes;
if(hasCustomHusk)
{
skin = (void*)(&skins[p->player->skin]);
frame = 0;
}
Particle::spew(this); Particle::spew(this);
scale(3*scale()/2); scale(3*scale()/2);
if(hasCustomHusk){
flags |= MF_NOSQUISH; //K_Squish() automates spritexscale/spriteyscale & this flag prevents that at the cost of no squish visual when the kart husk hits the ground
fixed_t huskScale = FixedDiv(mapobjectscale, scale());
spritexscale(FixedMul(spritexscale(), huskScale));
spriteyscale(FixedMul(spriteyscale(), huskScale));
}
health = 1; health = 1;
state(S_KART_LEFTOVER_NOTIRES); state(!hasCustomHusk ? S_KART_LEFTOVER_NOTIRES : S_KART_LEFTOVER_CUSTOM);
cooldown(20); cooldown(20);
burning(burn_duration()); burning(burn_duration());
@ -326,9 +345,9 @@ struct Kart : Mobj
voice(sfx_die00); voice(sfx_die00);
} }
if (Mobj* p = player(); Mobj::valid(p)) if(pValid)
{ {
if (p->player && skins[p->player->skin].flags & SF_BADNIK) if((skins[p->player->skin].flags & SF_BADNIK))
{ {
P_SpawnBadnikExplosion(p); P_SpawnBadnikExplosion(p);
p->spritescale({2*FRACUNIT, 2*FRACUNIT}); p->spritescale({2*FRACUNIT, 2*FRACUNIT});
@ -446,7 +465,7 @@ private:
P_PlayDeathSound(p); P_PlayDeathSound(p);
} }
// First tick after hitlag: destroyed kart appears! // First tick after hitlag: destroyed kart appears! State will change away from S_INVISIBLE inside destroy() where S_INVISIBLE was set in static spawn()
if (state()->num() == S_INVISIBLE) if (state()->num() == S_INVISIBLE)
{ {
destroy(); destroy();

View file

@ -9880,10 +9880,12 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
case MT_KART_LEFTOVER: case MT_KART_LEFTOVER:
{ {
Obj_DestroyedKartThink(mobj); Obj_DestroyedKartThink(mobj);
if (P_MobjWasRemoved(mobj)) if (P_MobjWasRemoved(mobj))
{ {
return false; return false;
} }
break; break;
} }