From 1adfc7f2a4272f9748fe39ce12d3864b3455d429 Mon Sep 17 00:00:00 2001 From: toaster Date: Sun, 12 Nov 2023 17:29:54 +0000 Subject: [PATCH] TRICKSTATE_FORWARD blast effect Fun and simple papersprite buffoonery Hey remember when the author of this commit thought papersprites would be a one-off side feature Also fixes a potential invalid dereference when getting the color for MT_SIDETRICK --- src/deh_tables.c | 2 ++ src/info.c | 33 ++++++++++++++++++++++-- src/info.h | 3 +++ src/k_kart.c | 34 ++++++++++++++++++++++--- src/p_mobj.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 133 insertions(+), 5 deletions(-) diff --git a/src/deh_tables.c b/src/deh_tables.c index 4b11f9421..f951e365a 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -3902,6 +3902,7 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_SIDETRICK", "S_BACKTRICK", + "S_FORWARDTRICK", // DEZ Ring Shooter "S_TIREGRABBER", @@ -5664,6 +5665,7 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_SMOOTHLANDING", "MT_TRICKINDICATOR", "MT_SIDETRICK", + "MT_FORWARDTRICK", "MT_TIREGRABBER", "MT_RINGSHOOTER", diff --git a/src/info.c b/src/info.c index 4e93c7473..51cfc2b63 100644 --- a/src/info.c +++ b/src/info.c @@ -641,6 +641,7 @@ char sprnames[NUMSPRITES + 1][5] = "TRK4", "TRK5", "TRK6", + "TRK7", "TIRG", // Tire grabbers "RSHT", // DEZ Ring Shooter @@ -4681,8 +4682,9 @@ state_t states[NUMSTATES] = {SPR_NULL, 0, 1, {NULL}, 12, 1, S_TRICKINDICATOR_UNDERLAY_ARROW2}, // S_TRICKINDICATOR_UNDERLAY_ARROW, {SPR_TRK4, FF_FULLBRIGHT|FF_ANIMATE|FF_PAPERSPRITE, 13, {NULL}, 12, 1, S_INVISIBLE}, // S_TRICKINDICATOR_UNDERLAY_ARROW2, - {SPR_TRK5, FF_FULLBRIGHT|FF_ANIMATE|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_SIDETRICK, - {SPR_TRK6, FF_FULLBRIGHT|FF_ANIMATE|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_BACKTRICK, + {SPR_TRK5, FF_FULLBRIGHT|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_SIDETRICK, + {SPR_TRK6, FF_FULLBRIGHT|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_BACKTRICK, + {SPR_TRK7, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_ANIMATE, -1, {NULL}, 6, 4, S_NULL}, // S_FORWARDTRICK, {SPR_TIRG, FF_ANIMATE, -1, {NULL}, 1, 1, S_NULL}, // S_TIREGRABBER {SPR_RSHT, FF_PAPERSPRITE|0, -1, {NULL}, 0, 0, S_NULL}, // S_RINGSHOOTER_SIDE @@ -25432,6 +25434,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_FORWARDTRICK + -1, // doomednum + S_FORWARDTRICK, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 60*FRACUNIT, // radius + 86*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPTHING|MF_NOCLIPHEIGHT|MF_DONTENCOREMAP, // flags + S_NULL // raisestate + }, + { // MT_TIREGRABBER -1, // doomednum S_TIREGRABBER, // spawnstate diff --git a/src/info.h b/src/info.h index 54cb2ed75..1bb5cfdac 100644 --- a/src/info.h +++ b/src/info.h @@ -1198,6 +1198,7 @@ typedef enum sprite SPR_TRK4, SPR_TRK5, SPR_TRK6, + SPR_TRK7, SPR_TIRG, // Tire grabbers SPR_RSHT, // DEZ Ring Shooter @@ -5127,6 +5128,7 @@ typedef enum state S_SIDETRICK, S_BACKTRICK, + S_FORWARDTRICK, // DEZ Ring Shooter S_TIREGRABBER, @@ -6928,6 +6930,7 @@ typedef enum mobj_type MT_SMOOTHLANDING, MT_TRICKINDICATOR, MT_SIDETRICK, + MT_FORWARDTRICK, MT_TIREGRABBER, MT_RINGSHOOTER, diff --git a/src/k_kart.c b/src/k_kart.c index 5831acbde..8162c1520 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -12397,9 +12397,37 @@ void K_MoveKartPlayer(player_t *player, boolean onground) } INT32 j; + skincolornum_t trickcolor = SKINCOLOR_NONE; - if (player->trickpanel == TRICKSTATE_FORWARD) - ; // Not yet sprited + if (P_MobjWasRemoved(player->trickIndicator) == false) + trickcolor = player->trickIndicator->color; + + if (player->trickpanel == TRICKSTATE_FORWARD) + { + for (j = 0; j < 2; j++) + { + mobj_t *fwush = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_FORWARDTRICK); + + P_SetTarget(&fwush->target, player->mo); + fwush->hitlag = TRICKLAG; + fwush->color = trickcolor; + fwush->renderflags |= RF_DONTDRAW; + fwush->flags2 |= MF2_AMBUSH; // don't interp on first think + fwush->threshold = 0; + + fwush->movedir = player->mo->angle; + if (j == 0) + { + fwush->angle = fwush->old_angle = fwush->movedir + ANGLE_135; + fwush->movefactor = 1; + } + else + { + fwush->angle = fwush->old_angle = fwush->movedir - ANGLE_135; + fwush->movefactor = -1; + } + } + } else for (j = 0; j < 8; j++, baseangle += angledelta) { mobj_t *swipe = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_SIDETRICK); @@ -12409,7 +12437,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) P_SetTarget(&swipe->target, player->mo); swipe->hitlag = TRICKLAG; - swipe->color = player->trickIndicator->color; + swipe->color = trickcolor; swipe->angle = baseangle + ANGLE_90; swipe->renderflags |= RF_DONTDRAW; swipe->flags2 |= MF2_AMBUSH; // don't interp on first think diff --git a/src/p_mobj.c b/src/p_mobj.c index 56c94b3ac..a37758add 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8537,6 +8537,72 @@ static boolean P_MobjRegularThink(mobj_t *mobj) } break; } + case MT_FORWARDTRICK: + { + fixed_t destx, desty; + fixed_t zoff = 0; + + if (!mobj->target + || !mobj->target->health + || !mobj->target->player + || mobj->target->player->trickpanel != TRICKSTATE_FORWARD) + { + P_RemoveMobj(mobj); + return false; + } + + // Flicker every other frame from first visibility + if (mobj->flags2 & MF2_BOSSDEAD) + { + mobj->renderflags |= RF_DONTDRAW; + } + else + { + mobj->renderflags &= ~RF_DONTDRAW; + mobj->renderflags |= (mobj->target->renderflags & RF_DONTDRAW); + } + + mobj->eflags = (mobj->eflags & ~MFE_VERTICALFLIP)|(mobj->target->eflags & MFE_VERTICALFLIP); + mobj->flags2 = ((mobj->flags2 & ~MF2_OBJECTFLIP)|(mobj->target->flags2 & MF2_OBJECTFLIP)) ^ MF2_BOSSDEAD; + + // sweeping effect + const fixed_t sweep = FixedMul(FRACUNIT - (mobj->threshold * 2), mobj->radius); + + mobj->threshold += FRACUNIT/(7*4); + if (mobj->threshold > FRACUNIT) + mobj->threshold -= FRACUNIT; + + P_InstaScale(mobj, mobj->target->scale); + + destx = mobj->target->x; + desty = mobj->target->y; + + destx += P_ReturnThrustX(mobj, mobj->movedir, sweep); + desty += P_ReturnThrustY(mobj, mobj->movedir, sweep); + + const fixed_t sideways = P_ReturnThrustY(mobj, mobj->angle - mobj->movedir, mobj->radius); + destx += P_ReturnThrustX(mobj, mobj->movedir + ANGLE_90, sideways); + desty += P_ReturnThrustY(mobj, mobj->movedir + ANGLE_90, sideways); + + if (mobj->eflags & MFE_VERTICALFLIP) + zoff += mobj->target->height - (mobj->height + 18*mobj->scale); + else + zoff += 18*mobj->scale; + + // Necessary to "ride" on Garden Top + zoff += mobj->target->sprzoff; + + if (mobj->flags2 & MF2_AMBUSH) + { + P_SetOrigin(mobj, destx, desty, mobj->target->z + zoff); + mobj->flags2 &= ~MF2_AMBUSH; + } + else + { + P_MoveOrigin(mobj, destx, desty, mobj->target->z + zoff); + } + break; + } case MT_LIGHTNINGSHIELD: { if (!mobj->target || !mobj->target->health || !mobj->target->player