From c9d72499f1cdb807dff63a33266892e45f904069 Mon Sep 17 00:00:00 2001 From: AJ Martinez Date: Sat, 4 Nov 2023 22:56:58 -0700 Subject: [PATCH 01/37] Allow half-speed turning for side tricks --- src/k_kart.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 8f6337a08..128f930a4 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -9415,9 +9415,9 @@ INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue) return 0; } - if (player->trickpanel != 0 && player->trickpanel < 4) + if (player->trickpanel == 1 || player->trickpanel == 5) { - // No turning during trick panel unless you did the upwards trick (4) + // Forward trick or rising from trickpanel return 0; } @@ -9513,6 +9513,12 @@ INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue) // Weight has a small effect on turning turnfixed = FixedMul(turnfixed, weightadjust); + // Side trick + if (player->trickpanel == 2 || player->trickpanel == 3) + { + turnfixed /= 2; + } + return (turnfixed / FRACUNIT); } @@ -12025,7 +12031,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) } P_InstaThrust(player->mo, player->mo->angle, max(basespeed, speed*3)); - player->trickpanel = 2; + player->trickpanel = 5; } else if (cmd->throwdir < 0) { From 120b567ba2514d67104d5a08a810ea1d833a55c0 Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 6 Nov 2023 01:09:06 +0000 Subject: [PATCH 02/37] K_DoPogoSpring: Handle player->trickpanel set directly --- src/k_kart.c | 3 +++ src/k_terrain.c | 2 -- src/objects/dash-rings.c | 2 -- src/p_map.c | 6 ------ 4 files changed, 3 insertions(+), 10 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 088421b2b..af197a578 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -6253,6 +6253,9 @@ void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound) if (mo->player) { + mo->player->trickpanel = 1; + mo->player->pflags |= PF_TRICKDELAY; + if (mo->player->sneakertimer) { thrust = FixedMul(thrust, 5*FRACUNIT/4); diff --git a/src/k_terrain.c b/src/k_terrain.c index 36edb5261..6c114d343 100644 --- a/src/k_terrain.c +++ b/src/k_terrain.c @@ -485,8 +485,6 @@ void K_ProcessTerrainEffect(mobj_t *mo) fixed_t speed = FixedHypot(mo->momx, mo->momy); fixed_t upwards = 16 * terrain->trickPanel; - player->trickpanel = 1; - player->pflags |= PF_TRICKDELAY; K_DoPogoSpring(mo, upwards, 1); // Reduce speed diff --git a/src/objects/dash-rings.c b/src/objects/dash-rings.c index d40e341bb..0a09d5831 100644 --- a/src/objects/dash-rings.c +++ b/src/objects/dash-rings.c @@ -199,8 +199,6 @@ static void RegularDashRingLaunch(player_t *player, mobj_t *ring) static void RainbowDashRingLaunch(player_t *player, mobj_t *ring) { player->mo->eflags &= ~MFE_SPRUNG; - player->trickpanel = 1; - player->pflags |= PF_TRICKDELAY; K_DoPogoSpring(player->mo, 0, 0); DashRingLaunch(player, ring); } diff --git a/src/p_map.c b/src/p_map.c index 79b9ba59e..c096dab60 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -512,12 +512,6 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object) if (spring->thing_args[1]) { - if (object->player) - { - object->player->trickpanel = 1; - object->player->pflags |= PF_TRICKDELAY; - } - K_DoPogoSpring(object, 32< Date: Mon, 6 Nov 2023 01:11:29 +0000 Subject: [PATCH 03/37] Adjust PlayerPointerRemove macros + associated to check validity before removal --- src/d_clisrv.c | 2 +- src/g_game.c | 2 +- src/k_kart.c | 4 ++-- src/p_inter.c | 15 +++++++++++---- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 2bfc47f24..a48bb344d 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2540,7 +2540,7 @@ void CL_ClearPlayer(INT32 playernum) } #define PlayerPointerRemove(field) \ - if (field) \ + if (P_MobjWasRemoved(field) == false) \ { \ P_RemoveMobj(field); \ P_SetTarget(&field, NULL); \ diff --git a/src/g_game.c b/src/g_game.c index b42085fc9..3c796cae4 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2234,7 +2234,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) K_RemoveFollower(&players[player]); #define PlayerPointerRemove(field) \ - if (field) \ + if (P_MobjWasRemoved(field) == false) \ { \ P_RemoveMobj(field); \ P_SetTarget(&field, NULL); \ diff --git a/src/k_kart.c b/src/k_kart.c index af197a578..40298dbaf 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4063,7 +4063,7 @@ void K_InitStumbleIndicator(player_t *player) return; } - if (player->stumbleIndicator != NULL && P_MobjWasRemoved(player->stumbleIndicator) == false) + if (P_MobjWasRemoved(player->stumbleIndicator) == false) { P_RemoveMobj(player->stumbleIndicator); } @@ -4088,7 +4088,7 @@ void K_InitSliptideZipIndicator(player_t *player) return; } - if (player->stumbleIndicator != NULL && P_MobjWasRemoved(player->sliptideZipIndicator) == false) + if (P_MobjWasRemoved(player->sliptideZipIndicator) == false) { P_RemoveMobj(player->sliptideZipIndicator); } diff --git a/src/p_inter.c b/src/p_inter.c index f3b66694d..447744aaa 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2550,10 +2550,17 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, P_SetPlayerMobjState(player->mo, player->mo->info->deathstate); - if (player->sliptideZipIndicator && !P_MobjWasRemoved(player->sliptideZipIndicator)) - P_RemoveMobj(player->sliptideZipIndicator); - if (player->stumbleIndicator && !P_MobjWasRemoved(player->stumbleIndicator)) - P_RemoveMobj(player->stumbleIndicator); +#define PlayerPointerRemove(field) \ + if (P_MobjWasRemoved(field) == false) \ + { \ + P_RemoveMobj(field); \ + P_SetTarget(&field, NULL); \ + } + + PlayerPointerRemove(player->stumbleIndicator); + PlayerPointerRemove(player->sliptideZipIndicator); + +#undef PlayerPointerRemove if (type == DMG_TIMEOVER) { From 5ffae81b0860f45b67bbeb4084fc515199c2dbb8 Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 6 Nov 2023 01:13:13 +0000 Subject: [PATCH 04/37] Trick Indicator first pass The author of this commit doesn't know what it's doing --- src/d_clisrv.c | 1 + src/d_player.h | 1 + src/deh_tables.c | 7 +++ src/g_game.c | 1 + src/info.c | 39 +++++++++++++++ src/info.h | 13 +++++ src/k_kart.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++- src/k_kart.h | 2 + src/p_inter.c | 1 + src/p_mobj.c | 2 +- src/p_saveg.c | 19 ++++++- src/p_user.c | 1 + 12 files changed, 211 insertions(+), 3 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index a48bb344d..abcdb7580 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2551,6 +2551,7 @@ void CL_ClearPlayer(INT32 playernum) PlayerPointerRemove(players[playernum].followmobj); PlayerPointerRemove(players[playernum].stumbleIndicator); PlayerPointerRemove(players[playernum].sliptideZipIndicator); + PlayerPointerRemove(players[playernum].trickIndicator); #undef PlayerPointerRemove diff --git a/src/d_player.h b/src/d_player.h index cc176671c..c132ca4e9 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -893,6 +893,7 @@ struct player_t mobj_t *stumbleIndicator; mobj_t *sliptideZipIndicator; + mobj_t *trickIndicator; mobj_t *whip; mobj_t *hand; mobj_t *flickyAttacker; diff --git a/src/deh_tables.c b/src/deh_tables.c index 3023b70eb..5a7930152 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -3892,6 +3892,12 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_SMOOTHLANDING", + "S_TRICKINDICATOR_OVERLAY", + "S_TRICKINDICATOR_UNDERLAY", + "S_TRICKINDICATOR_OVERLAY_ARROW", + "S_TRICKINDICATOR_UNDERLAY_ARROW", + "S_TRICKINDICATOR_UNDERLAY_ARROW2", + // DEZ Ring Shooter "S_TIREGRABBER", "S_RINGSHOOTER_SIDE", @@ -5649,6 +5655,7 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_TRIPWIREBOOST", "MT_SMOOTHLANDING", + "MT_TRICKINDICATOR", "MT_TIREGRABBER", "MT_RINGSHOOTER", diff --git a/src/g_game.c b/src/g_game.c index 3c796cae4..3b4ca5125 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2244,6 +2244,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) PlayerPointerRemove(players[player].followmobj); PlayerPointerRemove(players[player].stumbleIndicator); PlayerPointerRemove(players[player].sliptideZipIndicator); + PlayerPointerRemove(players[player].trickIndicator); #undef PlayerPointerRemove diff --git a/src/info.c b/src/info.c index 23c3225ee..3b1ade0e5 100644 --- a/src/info.c +++ b/src/info.c @@ -631,6 +631,12 @@ char sprnames[NUMSPRITES + 1][5] = "TWBT", // Tripwire BLASTER "SMLD", // Smooth landing + // Trick Indicator + "TRK1", + "TRK2", + "TRK3", + "TRK4", + "TIRG", // Tire grabbers "RSHT", // DEZ Ring Shooter @@ -4662,6 +4668,12 @@ state_t states[NUMSTATES] = {SPR_SMLD, FF_FULLBRIGHT|FF_ADD|FF_ANIMATE, -1, {NULL}, 7, 2, S_NULL}, // S_SMOOTHLANDING + {SPR_TRK1, FF_FULLBRIGHT|FF_ANIMATE|FF_PAPERSPRITE|FF_ADD, -1, {NULL}, 3, 3, S_NULL}, // S_TRICKINDICATOR_OVERLAY, + {SPR_TRK2, FF_FULLBRIGHT|FF_ANIMATE|FF_PAPERSPRITE, -1, {NULL}, 3, 3, S_NULL}, // S_TRICKINDICATOR_UNDERLAY, + {SPR_TRK3, FF_FULLBRIGHT|FF_ANIMATE|FF_PAPERSPRITE|FF_ADD, 13, {NULL}, 12, 1, S_INVISIBLE}, // S_TRICKINDICATOR_OVERLAY_ARROW, + {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_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 {SPR_RSHT, FF_SEMIBRIGHT|FF_PAPERSPRITE|2, -1, {NULL}, 0, 0, S_NULL}, // S_RINGSHOOTER_NIPPLES @@ -25329,6 +25341,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_TRICKINDICATOR + -1, // doomednum + S_INVISIBLE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // 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 + 128*FRACUNIT, // radius + 128*FRACUNIT, // height + -1, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_NOCLIPTHING|MF_DONTENCOREMAP, // flags + S_NULL // raisestate + }, + { // MT_TIREGRABBER -1, // doomednum S_TIREGRABBER, // spawnstate diff --git a/src/info.h b/src/info.h index b57082a5f..0686c8262 100644 --- a/src/info.h +++ b/src/info.h @@ -1188,6 +1188,12 @@ typedef enum sprite SPR_TWBT, // Tripwire BLASTER SPR_SMLD, // Smooth landing + // Trick Indicator + SPR_TRK1, + SPR_TRK2, + SPR_TRK3, + SPR_TRK4, + SPR_TIRG, // Tire grabbers SPR_RSHT, // DEZ Ring Shooter @@ -5106,6 +5112,12 @@ typedef enum state S_SMOOTHLANDING, + S_TRICKINDICATOR_OVERLAY, + S_TRICKINDICATOR_UNDERLAY, + S_TRICKINDICATOR_OVERLAY_ARROW, + S_TRICKINDICATOR_UNDERLAY_ARROW, + S_TRICKINDICATOR_UNDERLAY_ARROW2, + // DEZ Ring Shooter S_TIREGRABBER, S_RINGSHOOTER_SIDE, @@ -6902,6 +6914,7 @@ typedef enum mobj_type MT_TRIPWIREBOOST, MT_SMOOTHLANDING, + MT_TRICKINDICATOR, MT_TIREGRABBER, MT_RINGSHOOTER, diff --git a/src/k_kart.c b/src/k_kart.c index 40298dbaf..34d635560 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4099,6 +4099,44 @@ void K_InitSliptideZipIndicator(player_t *player) P_SetTarget(&new->target, player->mo); } +void K_InitTrickIndicator(player_t *player) +{ + mobj_t *new = NULL; + + if (player == NULL) + { + return; + } + + if (player->mo == NULL || P_MobjWasRemoved(player->mo) == true) + { + return; + } + + if (P_MobjWasRemoved(player->trickIndicator) == false) + { + if (P_MobjWasRemoved(player->trickIndicator->tracer) == false) + { + P_RemoveMobj(player->trickIndicator->tracer); + } + + P_RemoveMobj(player->trickIndicator); + } + + new = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_TRICKINDICATOR); + + P_SetTarget(&player->trickIndicator, new); + P_SetTarget(&new->target, player->mo); + + mobj_t *secondlayer = P_SpawnMobjFromMobj(new, 0, 0, 0, MT_OVERLAY); + + P_SetTarget(&new->tracer, secondlayer); + P_SetTarget(&secondlayer->target, new); + + secondlayer->dispoffset = 1; + secondlayer->flags |= MF_DONTENCOREMAP; +} + void K_UpdateStumbleIndicator(player_t *player) { const angle_t fudge = ANG15; @@ -4282,6 +4320,49 @@ void K_UpdateSliptideZipIndicator(player_t *player) } } +void K_UpdateTrickIndicator(player_t *player) +{ + mobj_t *mobj = NULL; + + if (player == NULL) + { + return; + } + + if (player->mo == NULL || P_MobjWasRemoved(player->mo) == true) + { + return; + } + + if (player->trickIndicator == NULL + || P_MobjWasRemoved(player->trickIndicator) == true + || player->trickIndicator->tracer == NULL + || P_MobjWasRemoved(player->trickIndicator->tracer) == true) + { + K_InitTrickIndicator(player); + return; + } + + mobj = player->trickIndicator; + + const fixed_t onidistance = 200*mapobjectscale; + + P_MoveOrigin( + mobj, + player->mo->x + P_ReturnThrustX(player->mo, player->mo->angle, onidistance), + player->mo->y + P_ReturnThrustY(player->mo, player->mo->angle, onidistance), + player->mo->z + (player->mo->height / 2)); + mobj->angle = player->mo->angle + ANGLE_90; + + if (player->trickpanel == 0) + { + P_SetScale(mobj, mobj->destscale = player->mo->scale); + + P_SetMobjState(mobj, S_INVISIBLE); + P_SetMobjState(mobj->tracer, S_INVISIBLE); + } +} + static boolean K_LastTumbleBounceCondition(player_t *player) { return (player->tumbleBounces > TUMBLEBOUNCES && player->tumbleHeight < 60); @@ -6256,6 +6337,16 @@ void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound) mo->player->trickpanel = 1; mo->player->pflags |= PF_TRICKDELAY; + if (P_MobjWasRemoved(mo->player->trickIndicator) == false) + { + mo->player->trickIndicator->rollangle = 0; + P_SetMobjState(mo->player->trickIndicator, S_TRICKINDICATOR_UNDERLAY); + if (P_MobjWasRemoved(mo->player->trickIndicator->tracer) == false) + { + P_SetMobjState(mo->player->trickIndicator->tracer, S_TRICKINDICATOR_OVERLAY); + } + } + if (mo->player->sneakertimer) { thrust = FixedMul(thrust, 5*FRACUNIT/4); @@ -8700,8 +8791,8 @@ void K_KartPlayerAfterThink(player_t *player) K_KartResetPlayerColor(player); K_UpdateStumbleIndicator(player); - K_UpdateSliptideZipIndicator(player); + K_UpdateTrickIndicator(player); // Move held objects (Bananas, Orbinaut, etc) K_MoveHeldObjects(player); @@ -11966,6 +12057,11 @@ void K_MoveKartPlayer(player_t *player, boolean onground) K_trickPanelTimingVisual(player, momz); + if (P_MobjWasRemoved(player->trickIndicator) == false) + { + player->trickIndicator->destscale = FixedMul(speedmult + FRACUNIT, mapobjectscale); + } + // streaks: if (momz*P_MobjFlip(player->mo) > 0) // only spawn those while you're going upwards relative to your current gravity { @@ -12031,11 +12127,21 @@ void K_MoveKartPlayer(player_t *player, boolean onground) { P_InstaThrust(player->mo, player->mo->angle + lr, max(basespeed, speed*5/2)); player->trickpanel = 2; + + if (P_MobjWasRemoved(player->trickIndicator) == false) + { + player->trickIndicator->rollangle = ANGLE_270; + } } else { P_InstaThrust(player->mo, player->mo->angle - lr, max(basespeed, speed*5/2)); player->trickpanel = 3; + + if (P_MobjWasRemoved(player->trickIndicator) == false) + { + player->trickIndicator->rollangle = ANGLE_90; + } } } else if (aimingcompare > TRICKTHRESHOLD) // forward/back trick @@ -12049,6 +12155,11 @@ void K_MoveKartPlayer(player_t *player, boolean onground) P_InstaThrust(player->mo, player->mo->angle, max(basespeed, speed*3)); player->trickpanel = 2; + + if (P_MobjWasRemoved(player->trickIndicator) == false) + { + player->trickIndicator->rollangle = 0; + } } else if (cmd->throwdir < 0) { @@ -12068,6 +12179,11 @@ void K_MoveKartPlayer(player_t *player, boolean onground) player->mo->momz += P_MobjFlip(player->mo)*48*mapobjectscale; player->trickpanel = 4; + + if (P_MobjWasRemoved(player->trickIndicator) == false) + { + player->trickIndicator->rollangle = ANGLE_180; + } } } #undef TRICKTHRESHOLD @@ -12084,6 +12200,15 @@ void K_MoveKartPlayer(player_t *player, boolean onground) { player->karthud[khud_trickcool] = TICRATE; } + + if (P_MobjWasRemoved(player->trickIndicator) == false) + { + P_SetMobjState(player->trickIndicator, S_TRICKINDICATOR_UNDERLAY_ARROW); + if (P_MobjWasRemoved(player->trickIndicator->tracer) == false) + { + P_SetMobjState(player->trickIndicator->tracer, S_TRICKINDICATOR_OVERLAY_ARROW); + } + } } } } diff --git a/src/k_kart.h b/src/k_kart.h index 7a4424f08..3f6293bba 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -120,8 +120,10 @@ void K_StumblePlayer(player_t *player); boolean K_CheckStumble(player_t *player, angle_t oldPitch, angle_t oldRoll, boolean fromAir); void K_InitStumbleIndicator(player_t *player); void K_InitSliptideZipIndicator(player_t *player); +void K_InitTrickIndicator(player_t *player); void K_UpdateStumbleIndicator(player_t *player); void K_UpdateSliptideZipIndicator(player_t *player); +void K_UpdateTrickIndicator(player_t *player); INT32 K_ExplodePlayer(player_t *player, mobj_t *inflictor, mobj_t *source); void K_DebtStingPlayer(player_t *player, mobj_t *source); void K_GiveBumpersToPlayer(player_t *player, player_t *victim, UINT8 amount); diff --git a/src/p_inter.c b/src/p_inter.c index 447744aaa..18a2f5e7c 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2559,6 +2559,7 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, PlayerPointerRemove(player->stumbleIndicator); PlayerPointerRemove(player->sliptideZipIndicator); + PlayerPointerRemove(player->trickIndicator); #undef PlayerPointerRemove diff --git a/src/p_mobj.c b/src/p_mobj.c index 1ada630c8..168fc86ac 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -12448,8 +12448,8 @@ void P_SpawnPlayer(INT32 playernum) p->griefValue = 0; K_InitStumbleIndicator(p); - K_InitSliptideZipIndicator(p); + K_InitTrickIndicator(p); if (gametyperules & GTR_ITEMARROWS) { diff --git a/src/p_saveg.c b/src/p_saveg.c index a1c3d1f64..865732692 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -65,7 +65,7 @@ savedata_cup_t cupsavedata; #define ARCHIVEBLOCK_RNG 0x7FAAB5BD // Note: This cannot be bigger -// than an UINT16 +// than an UINT16 (for now) typedef enum { AWAYVIEW = 0x0001, @@ -81,6 +81,7 @@ typedef enum HAND = 0x0400, FLICKYATTACKER = 0x0800, FLICKYCONTROLLER = 0x1000, + TRICKINDICATOR = 0x2000, } player_saveflags; static inline void P_ArchivePlayer(savebuffer_t *save) @@ -313,6 +314,9 @@ static void P_NetArchivePlayers(savebuffer_t *save) if (players[i].sliptideZipIndicator) flags |= SLIPTIDEZIP; + if (players[i].trickIndicator) + flags |= TRICKINDICATOR; + if (players[i].whip) flags |= WHIP; @@ -351,6 +355,9 @@ static void P_NetArchivePlayers(savebuffer_t *save) if (flags & SLIPTIDEZIP) WRITEUINT32(save->p, players[i].sliptideZipIndicator->mobjnum); + if (flags & TRICKINDICATOR) + WRITEUINT32(save->p, players[i].trickIndicator->mobjnum); + if (flags & WHIP) WRITEUINT32(save->p, players[i].whip->mobjnum); @@ -864,6 +871,9 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) if (flags & SLIPTIDEZIP) players[i].sliptideZipIndicator = (mobj_t *)(size_t)READUINT32(save->p); + if (flags & TRICKINDICATOR) + players[i].trickIndicator = (mobj_t *)(size_t)READUINT32(save->p); + if (flags & WHIP) players[i].whip = (mobj_t *)(size_t)READUINT32(save->p); @@ -5595,6 +5605,13 @@ static void P_RelinkPointers(void) if (!P_SetTarget(&players[i].sliptideZipIndicator, P_FindNewPosition(temp))) CONS_Debug(DBG_GAMELOGIC, "sliptideZipIndicator not found on player %d\n", i); } + if (players[i].trickIndicator) + { + temp = (UINT32)(size_t)players[i].trickIndicator; + players[i].trickIndicator = NULL; + if (!P_SetTarget(&players[i].trickIndicator, P_FindNewPosition(temp))) + CONS_Debug(DBG_GAMELOGIC, "trickIndicator not found on player %d\n", i); + } if (players[i].whip) { temp = (UINT32)(size_t)players[i].whip; diff --git a/src/p_user.c b/src/p_user.c index 419e78ab6..3d2aa4b37 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -3996,6 +3996,7 @@ void P_PlayerThink(player_t *player) PlayerPointerErase(player->followmobj); PlayerPointerErase(player->stumbleIndicator); PlayerPointerErase(player->sliptideZipIndicator); + PlayerPointerErase(player->trickIndicator); PlayerPointerErase(player->whip); PlayerPointerErase(player->hand); PlayerPointerErase(player->ringShooter); From bbe247733185defcf817e135edac27c2967ae0fc Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 6 Nov 2023 14:47:54 +0000 Subject: [PATCH 05/37] Obj_RainbowDashRingSpawn: Fix copypaste error that could have resulted in out-of-bounds access --- src/objects/dash-rings.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objects/dash-rings.c b/src/objects/dash-rings.c index 0a09d5831..ba9fed39e 100644 --- a/src/objects/dash-rings.c +++ b/src/objects/dash-rings.c @@ -66,7 +66,7 @@ void Obj_RainbowDashRingSpawn(mobj_t *mobj) void Obj_DashRingSetup(mobj_t *mobj, mapthing_t *mthing) { - static const UINT8 numColors = sizeof(rainbow_colors) / sizeof(skincolornum_t); + static const UINT8 numColors = sizeof(ring_colors) / sizeof(skincolornum_t); const UINT8 additionalThrust = mthing->thing_args[1]; statenum_t ringState, overlayState; From b051ff4741f8ce5f3244fc5890ca8f27cb7ade5b Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 6 Nov 2023 14:48:23 +0000 Subject: [PATCH 06/37] P_SpawnGhostMobj: Set old_scale too --- src/p_user.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/p_user.c b/src/p_user.c index 3d2aa4b37..34ffc414c 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1163,6 +1163,7 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj) ghost->old_angle = (mobj->player ? mobj->player->old_drawangle2 : mobj->old_angle2); ghost->old_pitch = mobj->old_pitch2; ghost->old_roll = mobj->old_roll2; + ghost->old_scale = mobj->old_scale2; K_ReduceVFX(ghost, mobj->player); From e06d961574bbe4a26034fc0b3fe7ddd8ee2dcbd4 Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 6 Nov 2023 14:54:46 +0000 Subject: [PATCH 07/37] Further refinement to Trick Indicator behaviour - Set colour in K_DoPogoSpring based on relevant vertical momentum - Similar but seperate colour list to Dash Rings - Improve interp state handling when starting a Trick - Don't set to S_INVISIBLE every non-tricking frame - Don't follow the player's movement during the very end of a swipe animation - Add a catholocism blast of the outer D-Pad ring while tricking --- src/k_kart.c | 74 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 60 insertions(+), 14 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 34d635560..9095af29a 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4125,11 +4125,13 @@ void K_InitTrickIndicator(player_t *player) new = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_TRICKINDICATOR); + P_SetMobjState(new, S_INVISIBLE); P_SetTarget(&player->trickIndicator, new); P_SetTarget(&new->target, player->mo); mobj_t *secondlayer = P_SpawnMobjFromMobj(new, 0, 0, 0, MT_OVERLAY); + P_SetMobjState(secondlayer, S_INVISIBLE); P_SetTarget(&new->tracer, secondlayer); P_SetTarget(&secondlayer->target, new); @@ -4345,6 +4347,11 @@ void K_UpdateTrickIndicator(player_t *player) mobj = player->trickIndicator; + statenum_t test = (mobj->state-states); + + if (test >= S_TRICKINDICATOR_UNDERLAY_ARROW) + return; + const fixed_t onidistance = 200*mapobjectscale; P_MoveOrigin( @@ -4354,10 +4361,9 @@ void K_UpdateTrickIndicator(player_t *player) player->mo->z + (player->mo->height / 2)); mobj->angle = player->mo->angle + ANGLE_90; - if (player->trickpanel == 0) + if (player->trickpanel == 0 + && test != S_INVISIBLE) { - P_SetScale(mobj, mobj->destscale = player->mo->scale); - P_SetMobjState(mobj, S_INVISIBLE); P_SetMobjState(mobj->tracer, S_INVISIBLE); } @@ -6322,16 +6328,14 @@ void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound) mo->eflags |= MFE_SPRUNG; - if (vertispeed == 0) + if (vertispeed <= 0) { - thrust = P_AproxDistance(mo->momx, mo->momy) * P_MobjFlip(mo); - thrust = FixedMul(thrust, FINESINE(ANGLE_22h >> ANGLETOFINESHIFT)); - } - else - { - thrust = vertispeed * P_MobjFlip(mo); + vertispeed = P_AproxDistance(mo->momx, mo->momy); + vertispeed = FixedMul(vertispeed, FINESINE(ANGLE_22h >> ANGLETOFINESHIFT)); } + thrust = vertispeed * P_MobjFlip(mo); + if (mo->player) { mo->player->trickpanel = 1; @@ -6339,11 +6343,46 @@ void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound) if (P_MobjWasRemoved(mo->player->trickIndicator) == false) { - mo->player->trickIndicator->rollangle = 0; - P_SetMobjState(mo->player->trickIndicator, S_TRICKINDICATOR_UNDERLAY); - if (P_MobjWasRemoved(mo->player->trickIndicator->tracer) == false) + mobj_t *trickIndicator = mo->player->trickIndicator; + + P_SetScale(trickIndicator, + trickIndicator->destscale + = trickIndicator->old_scale + = trickIndicator->old_scale2 + = mo->scale/4); + trickIndicator->rollangle = 0; + + static const skincolornum_t trick_colors[] = { + SKINCOLOR_GREY, // trickPanel == 1 + SKINCOLOR_TAN, + SKINCOLOR_YELLOW, // trickPanel == 2 + SKINCOLOR_TANGERINE, + SKINCOLOR_KETCHUP, // trickPanel == 3 + SKINCOLOR_MOONSET, + SKINCOLOR_ULTRAMARINE, // trickPanel == 4 + }; + static const UINT8 numColors = sizeof(trick_colors) / sizeof(skincolornum_t); + + const fixed_t step = 8*FRACUNIT; + fixed_t trickcol = ((vertispeed - (step/2)) / step) - 1; + if (trickcol < 0) + trickcol = 0; + trickIndicator->color = trick_colors[min(trickcol, numColors - 1)]; + + P_SetMobjState(trickIndicator, S_TRICKINDICATOR_UNDERLAY); + + if (P_MobjWasRemoved(trickIndicator->tracer) == false) { - P_SetMobjState(mo->player->trickIndicator->tracer, S_TRICKINDICATOR_OVERLAY); + P_SetScale(trickIndicator->tracer, + trickIndicator->tracer->destscale + = trickIndicator->tracer->old_scale + = trickIndicator->tracer->old_scale2 + = trickIndicator->destscale); + trickIndicator->tracer->rollangle = 0; + + trickIndicator->tracer->color = mo->player->trickIndicator->color; + + P_SetMobjState(trickIndicator->tracer, S_TRICKINDICATOR_OVERLAY); } } @@ -12203,6 +12242,13 @@ void K_MoveKartPlayer(player_t *player, boolean onground) if (P_MobjWasRemoved(player->trickIndicator) == false) { + mobj_t *catholocismBlast = P_SpawnGhostMobj(player->trickIndicator); + catholocismBlast->height = 1; + catholocismBlast->destscale *= 2; + catholocismBlast->fuse = 12; + catholocismBlast->rollangle = 0; + catholocismBlast->dispoffset = -1; + P_SetMobjState(player->trickIndicator, S_TRICKINDICATOR_UNDERLAY_ARROW); if (P_MobjWasRemoved(player->trickIndicator->tracer) == false) { From 2ecfe2f50fd37f232c153be920600d32841fcaa2 Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 6 Nov 2023 14:55:28 +0000 Subject: [PATCH 08/37] K_DoPogoSpring: Don't set Trick state if Player is in pain --- src/k_kart.c | 83 +++++++++++++++++++++++++++------------------------- 1 file changed, 43 insertions(+), 40 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 9095af29a..e4ca70aff 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -6338,51 +6338,54 @@ void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound) if (mo->player) { - mo->player->trickpanel = 1; - mo->player->pflags |= PF_TRICKDELAY; - - if (P_MobjWasRemoved(mo->player->trickIndicator) == false) + if (!P_PlayerInPain(mo->player)) { - mobj_t *trickIndicator = mo->player->trickIndicator; + mo->player->trickpanel = 1; + mo->player->pflags |= PF_TRICKDELAY; - P_SetScale(trickIndicator, - trickIndicator->destscale - = trickIndicator->old_scale - = trickIndicator->old_scale2 - = mo->scale/4); - trickIndicator->rollangle = 0; - - static const skincolornum_t trick_colors[] = { - SKINCOLOR_GREY, // trickPanel == 1 - SKINCOLOR_TAN, - SKINCOLOR_YELLOW, // trickPanel == 2 - SKINCOLOR_TANGERINE, - SKINCOLOR_KETCHUP, // trickPanel == 3 - SKINCOLOR_MOONSET, - SKINCOLOR_ULTRAMARINE, // trickPanel == 4 - }; - static const UINT8 numColors = sizeof(trick_colors) / sizeof(skincolornum_t); - - const fixed_t step = 8*FRACUNIT; - fixed_t trickcol = ((vertispeed - (step/2)) / step) - 1; - if (trickcol < 0) - trickcol = 0; - trickIndicator->color = trick_colors[min(trickcol, numColors - 1)]; - - P_SetMobjState(trickIndicator, S_TRICKINDICATOR_UNDERLAY); - - if (P_MobjWasRemoved(trickIndicator->tracer) == false) + if (P_MobjWasRemoved(mo->player->trickIndicator) == false) { - P_SetScale(trickIndicator->tracer, - trickIndicator->tracer->destscale - = trickIndicator->tracer->old_scale - = trickIndicator->tracer->old_scale2 - = trickIndicator->destscale); - trickIndicator->tracer->rollangle = 0; + mobj_t *trickIndicator = mo->player->trickIndicator; - trickIndicator->tracer->color = mo->player->trickIndicator->color; + P_SetScale(trickIndicator, + trickIndicator->destscale + = trickIndicator->old_scale + = trickIndicator->old_scale2 + = mo->scale/4); + trickIndicator->rollangle = 0; - P_SetMobjState(trickIndicator->tracer, S_TRICKINDICATOR_OVERLAY); + static const skincolornum_t trick_colors[] = { + SKINCOLOR_GREY, // trickPanel == 1 + SKINCOLOR_TAN, + SKINCOLOR_YELLOW, // trickPanel == 2 + SKINCOLOR_TANGERINE, + SKINCOLOR_KETCHUP, // trickPanel == 3 + SKINCOLOR_MOONSET, + SKINCOLOR_ULTRAMARINE, // trickPanel == 4 + }; + static const UINT8 numColors = sizeof(trick_colors) / sizeof(skincolornum_t); + + const fixed_t step = 8*FRACUNIT; + fixed_t trickcol = ((vertispeed - (step/2)) / step) - 1; + if (trickcol < 0) + trickcol = 0; + trickIndicator->color = trick_colors[min(trickcol, numColors - 1)]; + + P_SetMobjState(trickIndicator, S_TRICKINDICATOR_UNDERLAY); + + if (P_MobjWasRemoved(trickIndicator->tracer) == false) + { + P_SetScale(trickIndicator->tracer, + trickIndicator->tracer->destscale + = trickIndicator->tracer->old_scale + = trickIndicator->tracer->old_scale2 + = trickIndicator->destscale); + trickIndicator->tracer->rollangle = 0; + + trickIndicator->tracer->color = mo->player->trickIndicator->color; + + P_SetMobjState(trickIndicator->tracer, S_TRICKINDICATOR_OVERLAY); + } } } From 2f62c0ff6b51ce5070c61d3645aeb252bc7e8cc8 Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 6 Nov 2023 15:00:38 +0000 Subject: [PATCH 09/37] P_SpawnGhostMobj: Also copy scalespeed --- src/p_user.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/p_user.c b/src/p_user.c index 34ffc414c..b348ad7b9 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1109,6 +1109,7 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj) P_SetTarget(&ghost->target, mobj); P_SetScale(ghost, mobj->scale); + ghost->scalespeed = mobj->scalespeed; ghost->destscale = mobj->scale; if (mobj->eflags & MFE_VERTICALFLIP) From e412b6ddd83e9614abe0dbf27cb34f3a27a2b03c Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 6 Nov 2023 19:12:26 +0000 Subject: [PATCH 10/37] Call K_trickPanelTimingVisual only once per tic, to prevent pie duplication --- src/k_kart.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index e4ca70aff..83d646425 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -12097,8 +12097,6 @@ void K_MoveKartPlayer(player_t *player, boolean onground) fixed_t basespeed = FixedMul(invertscale, K_GetKartSpeed(player, false, false)); // at WORSE, keep your normal speed when tricking. fixed_t speed = FixedMul(invertscale, FixedMul(speedmult, P_AproxDistance(player->mo->momx, player->mo->momy))); - K_trickPanelTimingVisual(player, momz); - if (P_MobjWasRemoved(player->trickIndicator) == false) { player->trickIndicator->destscale = FixedMul(speedmult + FRACUNIT, mapobjectscale); @@ -12148,7 +12146,6 @@ void K_MoveKartPlayer(player_t *player, boolean onground) player->pflags &= ~PF_TUMBLESOUND; player->tumbleHeight = 30; // Base tumble bounce height player->trickpanel = 0; - K_trickPanelTimingVisual(player, momz); // fail trick visual P_SetPlayerMobjState(player->mo, S_KART_SPINOUT); if (player->pflags & (PF_ITEMOUT|PF_EGGMANOUT)) { @@ -12236,8 +12233,6 @@ void K_MoveKartPlayer(player_t *player, boolean onground) player->mo->hitlag = TRICKLAG; player->mo->eflags &= ~MFE_DAMAGEHITLAG; - K_trickPanelTimingVisual(player, momz); - if (abs(momz) < FRACUNIT*99) // Let's use that as baseline for PERFECT trick. { player->karthud[khud_trickcool] = TICRATE; @@ -12260,6 +12255,8 @@ void K_MoveKartPlayer(player_t *player, boolean onground) } } } + + K_trickPanelTimingVisual(player, momz); } else if (player->trickpanel == 4 && P_IsObjectOnGround(player->mo)) // Upwards trick landed! { From f8a6449033d1d303ba945c73020b8cd93b75fb45 Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 6 Nov 2023 19:22:21 +0000 Subject: [PATCH 11/37] Further Trick Indicator refinement - Abstract K_TrickCatholocismBlast into its own function - Spawn one at an askance angle when you fail a trick for any reason - Indicator is slightly closer to the player - Smaller indicator base scale - Indicator becomes more translucent the larger it is - Swipe is at 1.5 scale relative to the indicator --- src/k_kart.c | 44 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 83d646425..4b0238114 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4322,6 +4322,20 @@ void K_UpdateSliptideZipIndicator(player_t *player) } } +static mobj_t *K_TrickCatholocismBlast(mobj_t *trickIndicator, fixed_t destscale, angle_t rollangle) +{ + // It's my last minute visual effect and I get to choose the ridiculous function name - toast 061123 + + mobj_t *catholocismBlast = P_SpawnGhostMobj(trickIndicator); // HOLY? + catholocismBlast->height = 1; + catholocismBlast->destscale = destscale; + catholocismBlast->fuse = 12; + catholocismBlast->rollangle = rollangle; + catholocismBlast->dispoffset = -1; + + return catholocismBlast; +} + void K_UpdateTrickIndicator(player_t *player) { mobj_t *mobj = NULL; @@ -4352,7 +4366,7 @@ void K_UpdateTrickIndicator(player_t *player) if (test >= S_TRICKINDICATOR_UNDERLAY_ARROW) return; - const fixed_t onidistance = 200*mapobjectscale; + const fixed_t onidistance = 150*mapobjectscale; P_MoveOrigin( mobj, @@ -4364,6 +4378,8 @@ void K_UpdateTrickIndicator(player_t *player) if (player->trickpanel == 0 && test != S_INVISIBLE) { + K_TrickCatholocismBlast(mobj, 1, ANGLE_22h); + P_SetMobjState(mobj, S_INVISIBLE); P_SetMobjState(mobj->tracer, S_INVISIBLE); } @@ -12099,7 +12115,18 @@ void K_MoveKartPlayer(player_t *player, boolean onground) if (P_MobjWasRemoved(player->trickIndicator) == false) { - player->trickIndicator->destscale = FixedMul(speedmult + FRACUNIT, mapobjectscale); + const fixed_t indicatormult = 3*(mapobjectscale/5); + player->trickIndicator->destscale = FixedMul(speedmult + FRACUNIT, indicatormult); + + fixed_t trans = ((player->trickIndicator->scale * 9)/indicatormult) - 9; + if (trans < 10) // it's fine if it stays barely visible imo + { + UINT32 renderflags = player->trickIndicator->renderflags & ~RF_TRANSMASK; + if (trans > 0) + renderflags |= (trans << RF_TRANSSHIFT); + + player->trickIndicator->renderflags = renderflags; + } } // streaks: @@ -12240,16 +12267,17 @@ void K_MoveKartPlayer(player_t *player, boolean onground) if (P_MobjWasRemoved(player->trickIndicator) == false) { - mobj_t *catholocismBlast = P_SpawnGhostMobj(player->trickIndicator); - catholocismBlast->height = 1; - catholocismBlast->destscale *= 2; - catholocismBlast->fuse = 12; - catholocismBlast->rollangle = 0; - catholocismBlast->dispoffset = -1; + K_TrickCatholocismBlast(player->trickIndicator, player->trickIndicator->scale*10, 0); + + P_InstaScale(player->trickIndicator, 3*mapobjectscale/2); + player->trickIndicator->old_scale = player->trickIndicator->scale; P_SetMobjState(player->trickIndicator, S_TRICKINDICATOR_UNDERLAY_ARROW); if (P_MobjWasRemoved(player->trickIndicator->tracer) == false) { + P_InstaScale(player->trickIndicator->tracer, player->trickIndicator->scale); + player->trickIndicator->tracer->old_scale = player->trickIndicator->tracer->scale; + P_SetMobjState(player->trickIndicator->tracer, S_TRICKINDICATOR_OVERLAY_ARROW); } } From 4ecc378bb6e67a603560dad4aaa331d6e11d9558 Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 6 Nov 2023 19:27:24 +0000 Subject: [PATCH 12/37] Make weakest Trick Indicator colour white instead of grey More opaque, due to additive behaviour --- src/k_kart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/k_kart.c b/src/k_kart.c index 4b0238114..78b7f32e8 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -6371,7 +6371,7 @@ void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound) trickIndicator->rollangle = 0; static const skincolornum_t trick_colors[] = { - SKINCOLOR_GREY, // trickPanel == 1 + SKINCOLOR_WHITE, // trickPanel == 1 -- was SKINCOLOR_GREY SKINCOLOR_TAN, SKINCOLOR_YELLOW, // trickPanel == 2 SKINCOLOR_TANGERINE, From b417c0655e558de13e486ba18e9ce83a4520ed4e Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 6 Nov 2023 21:44:55 +0000 Subject: [PATCH 13/37] Map command: If you provide `-force` and the level has no associated gametype, safely assume Race as the default instead of requiring a `-gt race` addition --- src/d_netcmd.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index b51f1408a..d5384170f 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2422,13 +2422,15 @@ static void Command_Map_f(void) // Let's just guess so we don't have to specify the gametype EVERY time... newgametype = G_GuessGametypeByTOL(mapheaderinfo[newmapnum-1]->typeoflevel); - if (newgametype == -1) + if (!option_force && newgametype == -1) { CONS_Alert(CONS_WARNING, M_GetText("%s (%s) doesn't support any known gametype!\n"), realmapname, G_BuildMapName(newmapnum)); Z_Free(realmapname); Z_Free(mapname); return; } + + newgametype = GT_RACE; // sensible default } } From aa0b626467a10dad85c5ce4eeff549c0bb8485c7 Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 6 Nov 2023 21:47:16 +0000 Subject: [PATCH 14/37] Trick catholic swipe needs to have all layers be fully visible, even at the peak of the arc --- src/k_kart.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/k_kart.c b/src/k_kart.c index 78b7f32e8..a88aceb54 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -12269,6 +12269,8 @@ void K_MoveKartPlayer(player_t *player, boolean onground) { K_TrickCatholocismBlast(player->trickIndicator, player->trickIndicator->scale*10, 0); + player->trickIndicator->renderflags &= ~RF_TRANSMASK; + P_InstaScale(player->trickIndicator, 3*mapobjectscale/2); player->trickIndicator->old_scale = player->trickIndicator->scale; From 8885a335e7889a2739afcbe5bb0bb35efd89d3a7 Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 6 Nov 2023 21:49:28 +0000 Subject: [PATCH 15/37] MT_MAGICIANBOX: Support gravflip --- src/p_mobj.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/p_mobj.c b/src/p_mobj.c index 168fc86ac..4b606bee0 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8420,6 +8420,12 @@ static boolean P_MobjRegularThink(mobj_t *mobj) { destx += FixedMul(mobj->radius*2, FINECOSINE((mobj->angle+ANGLE_90) >> ANGLETOFINESHIFT)); desty += FixedMul(mobj->radius*2, FINESINE((mobj->angle+ANGLE_90) >> ANGLETOFINESHIFT)); + + mobj->eflags = (mobj->eflags & ~MFE_VERTICALFLIP)|(mobj->target->eflags & MFE_VERTICALFLIP); + mobj->flags2 = (mobj->flags2 & ~MF2_OBJECTFLIP)|(mobj->target->flags2 & MF2_OBJECTFLIP); + + if (mobj->eflags & MFE_VERTICALFLIP) + zoff += mobj->target->height - mobj->height; } else if (mobj->state == &states[S_MAGICIANBOX_TOP]) // top { From 48d93ec9f6d8d71893026ba4bd1f76fd3845a597 Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 6 Nov 2023 21:54:40 +0000 Subject: [PATCH 16/37] Side Trick effect - Copiously reuses from MT_MAGICIANBOX, gomen - Also set the lookback frame, for extra toaster-swag zaza - Because this feature is so old it predates lookback!? --- src/deh_tables.c | 3 +++ src/info.c | 32 +++++++++++++++++++++++++++- src/info.h | 6 +++++- src/k_kart.c | 33 +++++++++++++++++++++++++++++ src/p_mobj.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++ src/p_user.c | 4 ++-- 6 files changed, 129 insertions(+), 4 deletions(-) diff --git a/src/deh_tables.c b/src/deh_tables.c index 5a7930152..1025c8d58 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -3898,6 +3898,8 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_TRICKINDICATOR_UNDERLAY_ARROW", "S_TRICKINDICATOR_UNDERLAY_ARROW2", + "S_SIDETRICK", + // DEZ Ring Shooter "S_TIREGRABBER", "S_RINGSHOOTER_SIDE", @@ -5656,6 +5658,7 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_SMOOTHLANDING", "MT_TRICKINDICATOR", + "MT_SIDETRICK", "MT_TIREGRABBER", "MT_RINGSHOOTER", diff --git a/src/info.c b/src/info.c index 3b1ade0e5..da38478cf 100644 --- a/src/info.c +++ b/src/info.c @@ -631,11 +631,12 @@ char sprnames[NUMSPRITES + 1][5] = "TWBT", // Tripwire BLASTER "SMLD", // Smooth landing - // Trick Indicator + // Trick Effects "TRK1", "TRK2", "TRK3", "TRK4", + "TRK5", "TIRG", // Tire grabbers "RSHT", // DEZ Ring Shooter @@ -4674,6 +4675,8 @@ 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_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 {SPR_RSHT, FF_SEMIBRIGHT|FF_PAPERSPRITE|2, -1, {NULL}, 0, 0, S_NULL}, // S_RINGSHOOTER_NIPPLES @@ -25368,6 +25371,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_SIDETRICK + -1, // doomednum + S_SIDETRICK, // 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 + 36*FRACUNIT, // radius + 40*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 0686c8262..0963e1c93 100644 --- a/src/info.h +++ b/src/info.h @@ -1188,11 +1188,12 @@ typedef enum sprite SPR_TWBT, // Tripwire BLASTER SPR_SMLD, // Smooth landing - // Trick Indicator + // Trick Effects SPR_TRK1, SPR_TRK2, SPR_TRK3, SPR_TRK4, + SPR_TRK5, SPR_TIRG, // Tire grabbers SPR_RSHT, // DEZ Ring Shooter @@ -5118,6 +5119,8 @@ typedef enum state S_TRICKINDICATOR_UNDERLAY_ARROW, S_TRICKINDICATOR_UNDERLAY_ARROW2, + S_SIDETRICK, + // DEZ Ring Shooter S_TIREGRABBER, S_RINGSHOOTER_SIDE, @@ -6915,6 +6918,7 @@ typedef enum mobj_type MT_SMOOTHLANDING, MT_TRICKINDICATOR, + MT_SIDETRICK, MT_TIREGRABBER, MT_RINGSHOOTER, diff --git a/src/k_kart.c b/src/k_kart.c index a88aceb54..e892aa851 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -12189,6 +12189,10 @@ void K_MoveKartPlayer(player_t *player, boolean onground) #define TRICKTHRESHOLD (KART_FULLTURN/4) if (aimingcompare < -TRICKTHRESHOLD) // side trick { + angle_t sidetrickspeed = ANG30; + const angle_t angledelta = FixedAngle(36*FRACUNIT); + angle_t baseangle = player->mo->angle + angledelta/2; + if (cmd->turning > 0) { P_InstaThrust(player->mo, player->mo->angle + lr, max(basespeed, speed*5/2)); @@ -12198,6 +12202,9 @@ void K_MoveKartPlayer(player_t *player, boolean onground) { player->trickIndicator->rollangle = ANGLE_270; } + + player->drawangle -= ANGLE_45; + P_SetPlayerMobjState(player->mo, S_KART_FAST_LOOK_L); } else { @@ -12208,6 +12215,32 @@ void K_MoveKartPlayer(player_t *player, boolean onground) { player->trickIndicator->rollangle = ANGLE_90; } + + sidetrickspeed = InvAngle(sidetrickspeed); + + player->drawangle += ANGLE_45; + P_SetPlayerMobjState(player->mo, S_KART_FAST_LOOK_R); + } + + INT32 j; + + for (j = 0; j < 8; j++, baseangle += angledelta) + { + mobj_t *swipe = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_SIDETRICK); + P_SetTarget(&swipe->target, player->mo); + swipe->hitlag = TRICKLAG; + swipe->color = player->trickIndicator->color; + swipe->angle = baseangle + ANGLE_90; + swipe->renderflags |= RF_DONTDRAW; + swipe->flags2 |= MF2_AMBUSH; // don't interp on first think + swipe->movedir = sidetrickspeed; + swipe->frame |= (j % 4); + + // This is so they make a 10-sided shape with one-sprite gap + if (j != 3) + continue; + + baseangle += angledelta; } } else if (aimingcompare > TRICKTHRESHOLD) // forward/back trick diff --git a/src/p_mobj.c b/src/p_mobj.c index 4b606bee0..5c9f1f301 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8446,6 +8446,61 @@ static boolean P_MobjRegularThink(mobj_t *mobj) } break; } + case MT_SIDETRICK: + { + fixed_t destx, desty; + fixed_t zoff = 0; + + if (!mobj->target + || !mobj->target->health + || !mobj->target->player + || (mobj->target->player->trickpanel != 2 + && mobj->target->player->trickpanel != 3) + ) + { + P_RemoveMobj(mobj); + return false; + } + + if (leveltime & 1) + { + mobj->renderflags |= RF_DONTDRAW; + } + else + { + mobj->renderflags &= ~RF_DONTDRAW; + mobj->renderflags |= (mobj->target->renderflags & RF_DONTDRAW); + } + + mobj->angle += mobj->movedir; + P_SetScale(mobj, mobj->target->scale); + + destx = mobj->target->x; + desty = mobj->target->y; + + destx += P_ReturnThrustX(mobj, mobj->angle - ANGLE_90, mobj->radius*2); + desty += P_ReturnThrustY(mobj, mobj->angle - ANGLE_90, mobj->radius*2); + + mobj->eflags = (mobj->eflags & ~MFE_VERTICALFLIP)|(mobj->target->eflags & MFE_VERTICALFLIP); + mobj->flags2 = (mobj->flags2 & ~MF2_OBJECTFLIP)|(mobj->target->flags2 & MF2_OBJECTFLIP); + + if (mobj->eflags & MFE_VERTICALFLIP) + zoff += mobj->target->height - mobj->height; + + // 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 diff --git a/src/p_user.c b/src/p_user.c index b348ad7b9..2c9023e49 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2467,8 +2467,6 @@ void P_MovePlayer(player_t *player) } else { - K_KartMoveAnimation(player); - if (player->trickpanel == 2) { player->drawangle += ANGLE_22h; @@ -2479,6 +2477,8 @@ void P_MovePlayer(player_t *player) } else { + K_KartMoveAnimation(player); + player->drawangle = player->mo->angle; if (player->aizdriftturn) From 0016e8b9ec52b3a7e02d3983a4ca1699026aa8b1 Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 6 Nov 2023 22:17:53 +0000 Subject: [PATCH 17/37] Boost the Trick Panel boost gotten from sneakers/invinc to 2* --- src/k_kart.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index e892aa851..e3367a250 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -6405,13 +6405,9 @@ void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound) } } - if (mo->player->sneakertimer) + if (mo->player->sneakertimer || mo->player->invincibilitytimer) { - thrust = FixedMul(thrust, 5*FRACUNIT/4); - } - else if (mo->player->invincibilitytimer) - { - thrust = FixedMul(thrust, 9*FRACUNIT/8); + thrust = FixedMul(thrust, 2*FRACUNIT); } mo->player->tricktime = 0; // Reset post-hitlag timer From af24fcd4bd05e35a854bba83d282f78220b51288 Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 6 Nov 2023 22:18:27 +0000 Subject: [PATCH 18/37] Don't draw catholocism for other players Your relationship with christ is personal --- src/k_kart.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/k_kart.c b/src/k_kart.c index e3367a250..7beb2896b 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4123,17 +4123,21 @@ void K_InitTrickIndicator(player_t *player) P_RemoveMobj(player->trickIndicator); } + UINT32 invis = (RF_DONTDRAW & ~K_GetPlayerDontDrawFlag(player)); + new = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_TRICKINDICATOR); P_SetMobjState(new, S_INVISIBLE); P_SetTarget(&player->trickIndicator, new); P_SetTarget(&new->target, player->mo); + new->renderflags |= invis; mobj_t *secondlayer = P_SpawnMobjFromMobj(new, 0, 0, 0, MT_OVERLAY); P_SetMobjState(secondlayer, S_INVISIBLE); P_SetTarget(&new->tracer, secondlayer); P_SetTarget(&secondlayer->target, new); + secondlayer->renderflags |= invis; secondlayer->dispoffset = 1; secondlayer->flags |= MF_DONTENCOREMAP; From 49fb2fe6b63ce67d4cd9078e9b7fb35f2fbb115d Mon Sep 17 00:00:00 2001 From: AJ Martinez Date: Tue, 7 Nov 2023 03:46:11 -0700 Subject: [PATCH 19/37] WIP: Trick Panel crack --- src/d_netcmd.c | 3 ++- src/d_player.h | 1 + src/k_kart.c | 39 +++++++++++++++++++++++++++++++++------ src/lua_playerlib.c | 4 ++++ src/p_saveg.c | 2 ++ src/sounds.c | 4 ++++ src/sounds.h | 4 ++++ 7 files changed, 50 insertions(+), 7 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index d5384170f..776d8568d 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2430,7 +2430,8 @@ static void Command_Map_f(void) return; } - newgametype = GT_RACE; // sensible default + if (newgametype == -1) + newgametype = GT_RACE; // sensible default } } diff --git a/src/d_player.h b/src/d_player.h index c132ca4e9..d079de9a8 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -909,6 +909,7 @@ struct player_t INT16 incontrol; // -1 to -175 when spinning out or tumbling, 1 to 175 when not. Use to check for combo hits or emergency inputs. boolean markedfordeath; + boolean dotrickfx; UINT8 ringboxdelay; // Delay until Ring Box auto-activates UINT8 ringboxaward; // Where did we stop? diff --git a/src/k_kart.c b/src/k_kart.c index 7beb2896b..33a9ae545 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -8498,6 +8498,12 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) player->instaWhipCooldown--; } + if (player->dotrickfx && !player->mo->hitlag) + { + S_StartSound(player->mo, sfx_trick1); + player->dotrickfx = false; + } + // Don't screw up chain ring pickup/usage with instawhip charge. // If the button stays held, delay charge a bit. if (player->instaWhipChargeLockout) @@ -10920,9 +10926,10 @@ boolean K_FastFallBounce(player_t *player) player->pflags |= PF_UPDATEMYRESPAWN; + player->fastfall = 0; + player->mo->momz = bounce * P_MobjFlip(player->mo); - player->fastfall = 0; return true; } @@ -12193,6 +12200,9 @@ void K_MoveKartPlayer(player_t *player, boolean onground) const angle_t angledelta = FixedAngle(36*FRACUNIT); angle_t baseangle = player->mo->angle + angledelta/2; + S_StartSound(player->mo, sfx_trick0); + player->dotrickfx = true; + if (cmd->turning > 0) { P_InstaThrust(player->mo, player->mo->angle + lr, max(basespeed, speed*5/2)); @@ -12245,6 +12255,9 @@ void K_MoveKartPlayer(player_t *player, boolean onground) } else if (aimingcompare > TRICKTHRESHOLD) // forward/back trick { + S_StartSound(player->mo, sfx_trick0); + player->dotrickfx = true; + if (cmd->throwdir > 0) // back trick { if (player->mo->momz * P_MobjFlip(player->mo) > 0) @@ -12321,12 +12334,26 @@ void K_MoveKartPlayer(player_t *player, boolean onground) K_trickPanelTimingVisual(player, momz); } - else if (player->trickpanel == 4 && P_IsObjectOnGround(player->mo)) // Upwards trick landed! + else if (player->trickpanel && P_IsObjectOnGround(player->mo)) // Landed from trick { - //CONS_Printf("apply boost\n"); - S_StartSound(player->mo, sfx_s23c); - K_SpawnDashDustRelease(player); - player->trickboost = TICRATE - player->trickboostdecay; + if (player->fastfall) + { + player->mo->hitlag = 3; + K_SpawnDashDustRelease(player); + P_InstaThrust(player->mo, player->mo->angle, 30*FRACUNIT); + S_StartSound(player->mo, sfx_gshce); + player->fastfall = 0; // intentionally skip bounce + } + + if (player->trickpanel == 4) // upward trick + { + S_StartSound(player->mo, sfx_s23c); + K_SpawnDashDustRelease(player); + player->trickboost = TICRATE - player->trickboostdecay; + } + + player->sliptideZip += 300; + player->sliptideZipDelay = 0; player->trickpanel = player->trickboostdecay = 0; } diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 6fe1e325d..0bda04838 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -255,6 +255,8 @@ static int player_get(lua_State *L) lua_pushboolean(L, plr->flipDI); else if (fastcmp(field,"markedfordeath")) lua_pushboolean(L, plr->markedfordeath); + else if (fastcmp(field,"dotrickfx")) + lua_pushboolean(L, plr->dotrickfx); else if (fastcmp(field,"ringboxdelay")) lua_pushinteger(L, plr->ringboxdelay); else if (fastcmp(field,"ringboxaward")) @@ -737,6 +739,8 @@ static int player_set(lua_State *L) plr->flipDI = luaL_checkboolean(L, 3); else if (fastcmp(field,"markedfordeath")) plr->markedfordeath = luaL_checkboolean(L, 3); + else if (fastcmp(field,"dotrickfx")) + plr->dotrickfx = luaL_checkboolean(L, 3); else if (fastcmp(field,"ringboxdelay")) plr->ringboxdelay = luaL_checkinteger(L, 3); else if (fastcmp(field,"ringboxaward")) diff --git a/src/p_saveg.c b/src/p_saveg.c index 865732692..1860b84e8 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -560,6 +560,7 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEINT16(save->p, players[i].incontrol); WRITEUINT8(save->p, players[i].markedfordeath); + WRITEUINT8(save->p, players[i].dotrickfx); WRITEUINT8(save->p, players[i].ringboxdelay); WRITEUINT8(save->p, players[i].ringboxaward); @@ -1077,6 +1078,7 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].incontrol = READINT16(save->p); players[i].markedfordeath = READUINT8(save->p); + players[i].dotrickfx = READUINT8(save->p); players[i].ringboxdelay = READUINT8(save->p); players[i].ringboxaward = READUINT8(save->p); diff --git a/src/sounds.c b/src/sounds.c index cbb5836a2..dcfa01cc3 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -1119,6 +1119,10 @@ sfxinfo_t S_sfx[NUMSFX] = {"fshld2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Flame Shield burst"}, {"fshld3", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Flame Shield cooldown"}, + // RR - Trick Panel + {"trick0", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Trick confirm"}, + {"trick1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Trick"}, + // RR - Ballhog Charge {"bhog00", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Ballhog charging"}, {"bhog01", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Ballhog charging"}, diff --git a/src/sounds.h b/src/sounds.h index a19d2b4ed..0d686b3c2 100644 --- a/src/sounds.h +++ b/src/sounds.h @@ -1187,6 +1187,10 @@ typedef enum sfx_fshld2, sfx_fshld3, + // RR - Trick panels + sfx_trick0, + sfx_trick1, + // RR - Ballhog Charge sfx_bhog00, sfx_bhog01, From 73f67f4c94cbde829d714b276c63c716f863aef3 Mon Sep 17 00:00:00 2001 From: toaster Date: Tue, 7 Nov 2023 14:53:03 +0000 Subject: [PATCH 20/37] MT_MAGICIANBOX, MT_SIDETRICK: Fix some more interp issues Also guarantees that MT_SIDETRICK will be visible for the first frame of the trick, since it was invisible for the entire duration of catholocism. --- src/p_mobj.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 5c9f1f301..546d447aa 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8408,10 +8408,9 @@ static boolean P_MobjRegularThink(mobj_t *mobj) return true; } - mobj->extravalue1 += 1; - mobj->angle += ANG1*mobj->extravalue1; - P_SetScale(mobj, mobj->target->scale); + mobj->extravalue1 += 1; + P_InstaScale(mobj, mobj->target->scale); destx = mobj->target->x; desty = mobj->target->y; @@ -8438,6 +8437,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) if (mobj->flags2 & MF2_AMBUSH) { P_SetOrigin(mobj, destx, desty, mobj->target->z + zoff); + mobj->old_angle = mobj->angle; mobj->flags2 &= ~MF2_AMBUSH; } else @@ -8462,7 +8462,8 @@ static boolean P_MobjRegularThink(mobj_t *mobj) return false; } - if (leveltime & 1) + // Flicker every other frame from first visibility + if (mobj->flags2 & MF2_BOSSDEAD) { mobj->renderflags |= RF_DONTDRAW; } @@ -8472,8 +8473,13 @@ static boolean P_MobjRegularThink(mobj_t *mobj) 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; + + fixed_t scale = mobj->target->scale; + mobj->angle += mobj->movedir; - P_SetScale(mobj, mobj->target->scale); + P_InstaScale(mobj, scale); destx = mobj->target->x; desty = mobj->target->y; @@ -8481,9 +8487,6 @@ static boolean P_MobjRegularThink(mobj_t *mobj) destx += P_ReturnThrustX(mobj, mobj->angle - ANGLE_90, mobj->radius*2); desty += P_ReturnThrustY(mobj, mobj->angle - ANGLE_90, mobj->radius*2); - mobj->eflags = (mobj->eflags & ~MFE_VERTICALFLIP)|(mobj->target->eflags & MFE_VERTICALFLIP); - mobj->flags2 = (mobj->flags2 & ~MF2_OBJECTFLIP)|(mobj->target->flags2 & MF2_OBJECTFLIP); - if (mobj->eflags & MFE_VERTICALFLIP) zoff += mobj->target->height - mobj->height; @@ -8493,6 +8496,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) if (mobj->flags2 & MF2_AMBUSH) { P_SetOrigin(mobj, destx, desty, mobj->target->z + zoff); + mobj->old_angle = mobj->angle; mobj->flags2 &= ~MF2_AMBUSH; } else From c1f7546f9987358843fc119cf5426630cdf7f53b Mon Sep 17 00:00:00 2001 From: toaster Date: Tue, 7 Nov 2023 20:10:01 +0000 Subject: [PATCH 21/37] Sneaker/invincibility: Trick Panel launch multiplier is 1.5x, nerfed from 2x --- src/k_kart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/k_kart.c b/src/k_kart.c index 33a9ae545..53aaaf58a 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -6411,7 +6411,7 @@ void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound) if (mo->player->sneakertimer || mo->player->invincibilitytimer) { - thrust = FixedMul(thrust, 2*FRACUNIT); + thrust = FixedMul(thrust, (3*FRACUNIT)/2); } mo->player->tricktime = 0; // Reset post-hitlag timer From c3d34e937755df365634678cef89b38cc730c0c7 Mon Sep 17 00:00:00 2001 From: toaster Date: Tue, 7 Nov 2023 20:24:01 +0000 Subject: [PATCH 22/37] Back Trick effect A rising tornado swirling the opposite direction. Sprites do not currently exist, but it's a one-line emergency-break-glass change if there's any danger of not shopping with them --- src/deh_tables.c | 1 + src/info.c | 2 ++ src/info.h | 2 ++ src/k_kart.c | 74 ++++++++++++++++++++++++++++++------------------ src/p_mobj.c | 36 +++++++++++++++++++++-- 5 files changed, 84 insertions(+), 31 deletions(-) diff --git a/src/deh_tables.c b/src/deh_tables.c index 1025c8d58..5a087fcb0 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -3899,6 +3899,7 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_TRICKINDICATOR_UNDERLAY_ARROW2", "S_SIDETRICK", + "S_BACKTRICK", // DEZ Ring Shooter "S_TIREGRABBER", diff --git a/src/info.c b/src/info.c index da38478cf..a5fc9677d 100644 --- a/src/info.c +++ b/src/info.c @@ -637,6 +637,7 @@ char sprnames[NUMSPRITES + 1][5] = "TRK3", "TRK4", "TRK5", + "TRK6", "TIRG", // Tire grabbers "RSHT", // DEZ Ring Shooter @@ -4676,6 +4677,7 @@ state_t states[NUMSTATES] = {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_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 diff --git a/src/info.h b/src/info.h index 0963e1c93..01642bb20 100644 --- a/src/info.h +++ b/src/info.h @@ -1194,6 +1194,7 @@ typedef enum sprite SPR_TRK3, SPR_TRK4, SPR_TRK5, + SPR_TRK6, SPR_TIRG, // Tire grabbers SPR_RSHT, // DEZ Ring Shooter @@ -5120,6 +5121,7 @@ typedef enum state S_TRICKINDICATOR_UNDERLAY_ARROW2, S_SIDETRICK, + S_BACKTRICK, // DEZ Ring Shooter S_TIREGRABBER, diff --git a/src/k_kart.c b/src/k_kart.c index 53aaaf58a..351fbb112 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -12190,16 +12190,18 @@ void K_MoveKartPlayer(player_t *player, boolean onground) else if (!(player->pflags & PF_TRICKDELAY)) // don't allow tricking at the same frame you tumble obv { + // For tornado trick effects + angle_t tornadotrickspeed = ANG30; + const angle_t angledelta = FixedAngle(36*FRACUNIT); + angle_t baseangle = player->mo->angle + angledelta/2; + boolean fronttrick = false; + INT16 aimingcompare = abs(cmd->throwdir) - abs(cmd->turning); // Uses cmd->turning over steering intentionally. #define TRICKTHRESHOLD (KART_FULLTURN/4) if (aimingcompare < -TRICKTHRESHOLD) // side trick { - angle_t sidetrickspeed = ANG30; - const angle_t angledelta = FixedAngle(36*FRACUNIT); - angle_t baseangle = player->mo->angle + angledelta/2; - S_StartSound(player->mo, sfx_trick0); player->dotrickfx = true; @@ -12226,39 +12228,18 @@ void K_MoveKartPlayer(player_t *player, boolean onground) player->trickIndicator->rollangle = ANGLE_90; } - sidetrickspeed = InvAngle(sidetrickspeed); + tornadotrickspeed = InvAngle(tornadotrickspeed); player->drawangle += ANGLE_45; P_SetPlayerMobjState(player->mo, S_KART_FAST_LOOK_R); } - - INT32 j; - - for (j = 0; j < 8; j++, baseangle += angledelta) - { - mobj_t *swipe = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_SIDETRICK); - P_SetTarget(&swipe->target, player->mo); - swipe->hitlag = TRICKLAG; - swipe->color = player->trickIndicator->color; - swipe->angle = baseangle + ANGLE_90; - swipe->renderflags |= RF_DONTDRAW; - swipe->flags2 |= MF2_AMBUSH; // don't interp on first think - swipe->movedir = sidetrickspeed; - swipe->frame |= (j % 4); - - // This is so they make a 10-sided shape with one-sprite gap - if (j != 3) - continue; - - baseangle += angledelta; - } } else if (aimingcompare > TRICKTHRESHOLD) // forward/back trick { S_StartSound(player->mo, sfx_trick0); player->dotrickfx = true; - if (cmd->throwdir > 0) // back trick + if (cmd->throwdir > 0) // forward trick { if (player->mo->momz * P_MobjFlip(player->mo) > 0) { @@ -12272,8 +12253,12 @@ void K_MoveKartPlayer(player_t *player, boolean onground) { player->trickIndicator->rollangle = 0; } + + P_SetPlayerMobjState(player->mo, S_KART_FAST); + + fronttrick = true; } - else if (cmd->throwdir < 0) + else if (cmd->throwdir < 0) // back trick { player->mo->momx /= 3; player->mo->momy /= 3; @@ -12296,6 +12281,11 @@ void K_MoveKartPlayer(player_t *player, boolean onground) { player->trickIndicator->rollangle = ANGLE_180; } + + //tornadotrickspeed = InvAngle(tornadotrickspeed); + + //player->drawangle += ANGLE_45; + P_SetPlayerMobjState(player->mo, S_KART_FAST); } } #undef TRICKTHRESHOLD @@ -12311,6 +12301,34 @@ void K_MoveKartPlayer(player_t *player, boolean onground) player->karthud[khud_trickcool] = TICRATE; } + INT32 j; + + if (fronttrick == true) + ; // Not yet sprited + else for (j = 0; j < 8; j++, baseangle += angledelta) + { + mobj_t *swipe = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_SIDETRICK); + + if (player->trickpanel == 4) + P_SetMobjState(swipe, S_BACKTRICK); + + P_SetTarget(&swipe->target, player->mo); + swipe->hitlag = TRICKLAG; + swipe->color = player->trickIndicator->color; + swipe->angle = baseangle + ANGLE_90; + swipe->renderflags |= RF_DONTDRAW; + swipe->flags2 |= MF2_AMBUSH; // don't interp on first think + swipe->movedir = tornadotrickspeed; + swipe->frame |= (j % 4); + swipe->threshold = 0; + + // This is so they make a 10-sided shape with one-sprite gap + if (j != 3) + continue; + + baseangle += angledelta; + } + if (P_MobjWasRemoved(player->trickIndicator) == false) { K_TrickCatholocismBlast(player->trickIndicator, player->trickIndicator->scale*10, 0); diff --git a/src/p_mobj.c b/src/p_mobj.c index 546d447aa..46c42d9ca 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8454,9 +8454,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) if (!mobj->target || !mobj->target->health || !mobj->target->player - || (mobj->target->player->trickpanel != 2 - && mobj->target->player->trickpanel != 3) - ) + || mobj->target->player->trickpanel <= 1) { P_RemoveMobj(mobj); return false; @@ -8478,6 +8476,38 @@ static boolean P_MobjRegularThink(mobj_t *mobj) fixed_t scale = mobj->target->scale; + // sweeping effect + if (mobj->target->player->trickpanel == 4) + { + const fixed_t saferange = (20*FRACUNIT)/21; + if (mobj->threshold < -saferange) + { + mobj->threshold = -saferange; + mobj->flags2 |= MF2_AMBUSH; + } + else while (mobj->threshold > saferange) + { + mobj->threshold -= 2*saferange; + mobj->flags2 |= MF2_AMBUSH; + } + + scale = P_ReturnThrustX(mobj, FixedAngle(90*mobj->threshold), scale); + + // This funny dealie is to make it so default + // scale is placed as standard, + // but variant threshold shifts upwards + fixed_t extraoffset = FixedMul(mobj->info->height, mobj->target->scale - scale); + if (mobj->threshold < 0) + extraoffset /= 2; + + // And this makes it swooce across the object. + extraoffset += FixedMul(mobj->threshold, mobj->target->height); + + zoff += P_MobjFlip(mobj) * extraoffset; + + mobj->threshold += (saferange/8); + } + mobj->angle += mobj->movedir; P_InstaScale(mobj, scale); From 6f22c5261e5e96c1ef03f76490a4033f5331ead8 Mon Sep 17 00:00:00 2001 From: toaster Date: Tue, 7 Nov 2023 22:50:51 +0000 Subject: [PATCH 23/37] MT_POGOSPRING: Guarantee spawn of catholocism --- src/k_kart.c | 19 ++++++++++++++----- src/p_map.c | 8 ++------ 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index f875b96e0..628924e75 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -6336,6 +6336,7 @@ static void K_DoShrink(player_t *user) void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound) { fixed_t thrust = 0; + boolean dontapplymomz = false; if (mo->player && mo->player->spectator) return; @@ -6348,11 +6349,16 @@ void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound) mo->eflags |= MFE_SPRUNG; - if (vertispeed <= 0) + if (vertispeed == 0) { vertispeed = P_AproxDistance(mo->momx, mo->momy); vertispeed = FixedMul(vertispeed, FINESINE(ANGLE_22h >> ANGLETOFINESHIFT)); } + else if (vertispeed < 0) + { + dontapplymomz = 0; + vertispeed = -vertispeed; + } thrust = vertispeed * P_MobjFlip(mo); @@ -6422,11 +6428,14 @@ void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound) mo->player->fastfall = 0; } - mo->momz = FixedMul(thrust, mapobjectscale); - - if (mo->eflags & MFE_UNDERWATER) + if (dontapplymomz == false) { - mo->momz = FixedDiv(mo->momz, FixedSqrt(3*FRACUNIT)); + mo->momz = FixedMul(thrust, mapobjectscale); + + if (mo->eflags & MFE_UNDERWATER) + { + mo->momz = FixedDiv(mo->momz, FixedSqrt(3*FRACUNIT)); + } } P_ResetPitchRoll(mo); diff --git a/src/p_map.c b/src/p_map.c index c096dab60..b2693a122 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -427,12 +427,8 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) { if (spring->reactiontime == 0) { - object->player->tricktime = 0; // Reset post-hitlag timer - // Setup the boost for potential upwards trick, at worse, make it your regular max speed. (boost = curr speed*1.25) - object->player->trickboostpower = max(FixedDiv(object->player->speed, K_GetKartSpeed(object->player, false, false)) - FRACUNIT, 0)*125/100; - //CONS_Printf("Got boost: %d%\n", mo->player->trickboostpower*100 / FRACUNIT); - object->player->trickpanel = 1; - object->player->pflags |= PF_TRICKDELAY; + object->eflags &= ~MFE_SPRUNG; // needed to permit the following + K_DoPogoSpring(object, -vertispeed, 0); // negative so momz isn't modified } else { From 239388a1faa6b706177e1f18e3ce2f65faf23203 Mon Sep 17 00:00:00 2001 From: toaster Date: Tue, 7 Nov 2023 23:06:50 +0000 Subject: [PATCH 24/37] Add TRICKSTATE_ constants Replaces the magic numpers <-- typo I have left in for posterity --- src/d_player.h | 12 +++++++++++- src/k_bot.cpp | 4 ++-- src/k_director.cpp | 2 +- src/k_kart.c | 43 ++++++++++++++++++++++--------------------- src/k_terrain.c | 2 +- src/p_inter.c | 2 +- src/p_mobj.c | 6 +++--- src/p_user.c | 17 ++++++++++------- 8 files changed, 51 insertions(+), 37 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index d079de9a8..b4777e67c 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -261,6 +261,16 @@ typedef enum TRIPWIRE_BLASTER, } tripwirepass_t; +typedef enum +{ + TRICKSTATE_NONE = 0, + TRICKSTATE_READY, + TRICKSTATE_FORWARD, + TRICKSTATE_RIGHT, + TRICKSTATE_LEFT, + TRICKSTATE_BACK, +} trickstate_t; + typedef enum { // Unsynced, HUD or clientsided effects @@ -740,7 +750,7 @@ struct player_t UINT8 confirmVictim; // Player ID that you dealt damage to UINT8 confirmVictimDelay; // Delay before playing the sound - UINT8 trickpanel; // Trick panel state + UINT8 trickpanel; // Trick panel state - see trickstate_t UINT8 tricktime; // Increases while you're tricking. You can't input any trick until it's reached a certain threshold fixed_t trickboostpower; // Save the rough speed multiplier. Used for upwards tricks. UINT8 trickboostdecay; // used to know how long you've waited diff --git a/src/k_bot.cpp b/src/k_bot.cpp index 2d796758e..8c1894fba 100644 --- a/src/k_bot.cpp +++ b/src/k_bot.cpp @@ -1109,7 +1109,7 @@ static void K_BotTrick(player_t *player, ticcmd_t *cmd, const botcontroller_t *b return; } - if (player->trickpanel == 1) + if (player->trickpanel == TRICKSTATE_READY) { switch (botController->trick) { @@ -1521,7 +1521,7 @@ static void K_BuildBotTiccmdNormal(player_t *player, ticcmd_t *cmd) // Actual gameplay behaviors below this block! const botcontroller_t *botController = K_GetBotController(player->mo); - if (player->trickpanel != 0) + if (player->trickpanel != TRICKSTATE_NONE) { K_BotTrick(player, cmd, botController); diff --git a/src/k_director.cpp b/src/k_director.cpp index f04d2dfca..118786d63 100644 --- a/src/k_director.cpp +++ b/src/k_director.cpp @@ -221,7 +221,7 @@ private: bool can_change() const { - if (viewplayer()->trickpanel > 0) + if (viewplayer()->trickpanel != TRICKSTATE_NONE) { return false; } diff --git a/src/k_kart.c b/src/k_kart.c index 628924e75..15f0e28f7 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4379,7 +4379,7 @@ void K_UpdateTrickIndicator(player_t *player) player->mo->z + (player->mo->height / 2)); mobj->angle = player->mo->angle + ANGLE_90; - if (player->trickpanel == 0 + if (player->trickpanel == TRICKSTATE_NONE && test != S_INVISIBLE) { K_TrickCatholocismBlast(mobj, 1, ANGLE_22h); @@ -6366,7 +6366,7 @@ void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound) { if (!P_PlayerInPain(mo->player)) { - mo->player->trickpanel = 1; + mo->player->trickpanel = TRICKSTATE_READY; mo->player->pflags |= PF_TRICKDELAY; if (P_MobjWasRemoved(mo->player->trickIndicator) == false) @@ -8674,11 +8674,11 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) K_FlameDashLeftoverSmoke(player->mo); } - if (P_IsObjectOnGround(player->mo) && player->trickpanel != 0) + if (P_IsObjectOnGround(player->mo) && player->trickpanel != TRICKSTATE_NONE) { if (P_MobjFlip(player->mo) * player->mo->momz <= 0) { - player->trickpanel = 0; + player->trickpanel = TRICKSTATE_NONE; } } @@ -9589,7 +9589,7 @@ INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue) return 0; } - if (player->trickpanel == 1 || player->trickpanel == 5) + if (player->trickpanel == TRICKSTATE_READY || player->trickpanel == TRICKSTATE_FORWARD) { // Forward trick or rising from trickpanel return 0; @@ -9688,7 +9688,7 @@ INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue) turnfixed = FixedMul(turnfixed, weightadjust); // Side trick - if (player->trickpanel == 2 || player->trickpanel == 3) + if (player->trickpanel == TRICKSTATE_LEFT || player->trickpanel == TRICKSTATE_RIGHT) { turnfixed /= 2; } @@ -11140,7 +11140,7 @@ static void K_trickPanelTimingVisual(player_t *player, fixed_t momz) flame->sprite = SPR_TRCK; flame->frame = i|FF_FULLBRIGHT; - if (player->trickpanel <= 1 && !player->tumbleBounces) + if (player->trickpanel <= TRICKSTATE_READY && !player->tumbleBounces) { flame->tics = 2; flame->momx = player->mo->momx; @@ -11151,7 +11151,7 @@ static void K_trickPanelTimingVisual(player_t *player, fixed_t momz) { flame->tics = TICRATE; - if (player->trickpanel > 1) // we tricked + if (player->trickpanel > TRICKSTATE_READY) // we tricked { // Send the thing outwards via ghetto maths which involves redoing the whole 3d sphere again, witht the "vertical" angle shifted by 90 degrees. // There's probably a simplier way to do this the way I want to but this works. @@ -12015,7 +12015,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) } break; case KITEM_POGOSPRING: - if (ATTACK_IS_DOWN && !HOLDING_ITEM && onground && NO_HYUDORO && player->trickpanel == 0) + if (ATTACK_IS_DOWN && !HOLDING_ITEM && onground && NO_HYUDORO && player->trickpanel == TRICKSTATE_NONE) { K_PlayBoostTaunt(player->mo); //K_DoPogoSpring(player->mo, 32<mo->renderflags &= ~RF_BLENDMASK; } - if (player->trickpanel == 1) + if (player->trickpanel == TRICKSTATE_READY) { const angle_t lr = ANGLE_45; fixed_t momz = FixedDiv(player->mo->momz, mapobjectscale); // bring momz back to scale... @@ -12194,7 +12194,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) player->tumbleBounces = 1; player->pflags &= ~PF_TUMBLESOUND; player->tumbleHeight = 30; // Base tumble bounce height - player->trickpanel = 0; + player->trickpanel = TRICKSTATE_NONE; P_SetPlayerMobjState(player->mo, S_KART_SPINOUT); if (player->pflags & (PF_ITEMOUT|PF_EGGMANOUT)) { @@ -12222,7 +12222,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) if (cmd->turning > 0) { P_InstaThrust(player->mo, player->mo->angle + lr, max(basespeed, speed*5/2)); - player->trickpanel = 2; + player->trickpanel = TRICKSTATE_RIGHT; if (P_MobjWasRemoved(player->trickIndicator) == false) { @@ -12235,7 +12235,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) else { P_InstaThrust(player->mo, player->mo->angle - lr, max(basespeed, speed*5/2)); - player->trickpanel = 3; + player->trickpanel = TRICKSTATE_LEFT; if (P_MobjWasRemoved(player->trickIndicator) == false) { @@ -12261,7 +12261,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) } P_InstaThrust(player->mo, player->mo->angle, max(basespeed, speed*3)); - player->trickpanel = 5; + player->trickpanel = TRICKSTATE_FORWARD; if (P_MobjWasRemoved(player->trickIndicator) == false) { @@ -12287,7 +12287,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) //CONS_Printf("decay: %d\n", player->trickboostdecay); player->mo->momz += P_MobjFlip(player->mo)*48*mapobjectscale; - player->trickpanel = 4; + player->trickpanel = TRICKSTATE_BACK; if (P_MobjWasRemoved(player->trickIndicator) == false) { @@ -12303,7 +12303,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) #undef TRICKTHRESHOLD // Finalise everything. - if (player->trickpanel != 1) // just changed from 1? + if (player->trickpanel != TRICKSTATE_READY) // just changed from 1? { player->mo->hitlag = TRICKLAG; player->mo->eflags &= ~MFE_DAMAGEHITLAG; @@ -12315,13 +12315,13 @@ void K_MoveKartPlayer(player_t *player, boolean onground) INT32 j; - if (player->trickpanel == 5) + if (player->trickpanel == TRICKSTATE_FORWARD) ; // Not yet sprited else for (j = 0; j < 8; j++, baseangle += angledelta) { mobj_t *swipe = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_SIDETRICK); - if (player->trickpanel == 4) + if (player->trickpanel == TRICKSTATE_BACK) P_SetMobjState(swipe, S_BACKTRICK); P_SetTarget(&swipe->target, player->mo); @@ -12364,7 +12364,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) K_trickPanelTimingVisual(player, momz); } - else if (player->trickpanel && P_IsObjectOnGround(player->mo)) // Landed from trick + else if ((player->trickpanel != TRICKSTATE_NONE) && P_IsObjectOnGround(player->mo)) // Landed from trick { if (player->fastfall) { @@ -12375,7 +12375,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) player->fastfall = 0; // intentionally skip bounce } - if (player->trickpanel == 4) // upward trick + if (player->trickpanel == TRICKSTATE_BACK) // upward trick { S_StartSound(player->mo, sfx_s23c); K_SpawnDashDustRelease(player); @@ -12385,7 +12385,8 @@ void K_MoveKartPlayer(player_t *player, boolean onground) player->sliptideZip += 300; player->sliptideZipDelay = 0; - player->trickpanel = player->trickboostdecay = 0; + player->trickpanel = TRICKSTATE_NONE; + player->trickboostdecay = 0; } // Wait until we let go off the control stick to remove the delay diff --git a/src/k_terrain.c b/src/k_terrain.c index 6c114d343..d2d9a3f8a 100644 --- a/src/k_terrain.c +++ b/src/k_terrain.c @@ -549,7 +549,7 @@ void K_ProcessTerrainEffect(mobj_t *mo) P_InstaThrust(player->mo, thrustAngle, max(thrustSpeed, 2*playerSpeed)); player->dashpadcooldown = TICRATE/3; - player->trickpanel = 0; + player->trickpanel = TRICKSTATE_NONE; player->floorboost = 2; S_StartSound(player->mo, sfx_cdfm62); diff --git a/src/p_inter.c b/src/p_inter.c index 18a2f5e7c..fc7458ad6 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1692,7 +1692,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget target->player->roundscore = 0; } - target->player->trickpanel = 0; + target->player->trickpanel = TRICKSTATE_NONE; ACS_RunPlayerDeathScript(target->player); } diff --git a/src/p_mobj.c b/src/p_mobj.c index 46c42d9ca..efb668fec 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1147,7 +1147,7 @@ fixed_t P_GetMobjGravity(mobj_t *mo) P_PlayerFlip(mo); } - if (mo->player->trickpanel >= 2) + if (mo->player->trickpanel > TRICKSTATE_READY) { gravityadd = (5*gravityadd)/2; } @@ -8454,7 +8454,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) if (!mobj->target || !mobj->target->health || !mobj->target->player - || mobj->target->player->trickpanel <= 1) + || mobj->target->player->trickpanel <= TRICKSTATE_FORWARD) { P_RemoveMobj(mobj); return false; @@ -8477,7 +8477,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) fixed_t scale = mobj->target->scale; // sweeping effect - if (mobj->target->player->trickpanel == 4) + if (mobj->target->player->trickpanel == TRICKSTATE_BACK) { const fixed_t saferange = (20*FRACUNIT)/21; if (mobj->threshold < -saferange) diff --git a/src/p_user.c b/src/p_user.c index 1c7ce4ee6..81a5cd555 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -478,7 +478,7 @@ void P_ResetPlayer(player_t *player) player->onconveyor = 0; //player->drift = player->driftcharge = 0; - player->trickpanel = 0; + player->trickpanel = TRICKSTATE_NONE; player->glanceDir = 0; player->fastfall = 0; @@ -2467,13 +2467,16 @@ void P_MovePlayer(player_t *player) } else { - if (player->trickpanel == 2 || player->trickpanel == 5) // right/forward + if (player->trickpanel > TRICKSTATE_READY) { - player->drawangle += ANGLE_22h; - } - else if (player->trickpanel == 3 || player->trickpanel == 4) // left/back - { - player->drawangle -= ANGLE_22h; + if (player->trickpanel <= TRICKSTATE_RIGHT) // right/forward + { + player->drawangle += ANGLE_22h; + } + else //if (player->trickpanel >= TRICKSTATE_LEFT) // left/back + { + player->drawangle -= ANGLE_22h; + } } else { From 954bd85139740b8585614820c3327f42829eb24d Mon Sep 17 00:00:00 2001 From: AJ Martinez Date: Wed, 8 Nov 2023 01:52:07 -0700 Subject: [PATCH 25/37] WIP: Trickpanel crack experiments --- src/d_clisrv.c | 2 +- src/d_player.h | 10 +-- src/deh_tables.c | 4 +- src/g_game.c | 2 +- src/info.c | 9 +-- src/info.h | 7 +- src/k_kart.c | 154 ++++++++++++++++++++++++++++---------------- src/k_kart.h | 4 +- src/k_respawn.c | 3 +- src/lua_playerlib.c | 32 +++++---- src/p_inter.c | 2 +- src/p_mobj.c | 2 +- src/p_saveg.c | 40 ++++++------ src/p_user.c | 2 +- 14 files changed, 165 insertions(+), 108 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index abcdb7580..ce142ffd1 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2550,7 +2550,7 @@ void CL_ClearPlayer(INT32 playernum) PlayerPointerRemove(players[playernum].mo); PlayerPointerRemove(players[playernum].followmobj); PlayerPointerRemove(players[playernum].stumbleIndicator); - PlayerPointerRemove(players[playernum].sliptideZipIndicator); + PlayerPointerRemove(players[playernum].wavedashIndicator); PlayerPointerRemove(players[playernum].trickIndicator); #undef PlayerPointerRemove diff --git a/src/d_player.h b/src/d_player.h index b4777e67c..bd951e7c7 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -895,14 +895,16 @@ struct player_t UINT8 tripwireReboundDelay; // When failing Tripwire, brieftly lock out speed-based tripwire pass (anti-cheese) - UINT16 sliptideZip; // How long is our chained sliptide? Grant a proportional boost when it's over. - UINT8 sliptideZipDelay; // How long since the last sliptide? Only boost once you've been straightened out for a bit. - UINT16 sliptideZipBoost; // The actual boost granted from sliptideZip. + UINT16 wavedash; // How long is our chained sliptide? Grant a proportional boost when it's over. + UINT8 wavedashdelay; // How long since the last sliptide? Only boost once you've been straightened out for a bit. + UINT16 wavedashboost; // The actual boost granted from wavedash. + UINT16 trickdashboost; // The actual boost granted from wavedash. + boolean trickdash; UINT8 lastsafelap; mobj_t *stumbleIndicator; - mobj_t *sliptideZipIndicator; + mobj_t *wavedashIndicator; mobj_t *trickIndicator; mobj_t *whip; mobj_t *hand; diff --git a/src/deh_tables.c b/src/deh_tables.c index 5a087fcb0..c0d35b1b5 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -3314,7 +3314,7 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_MAGICIANBOXTOP", "S_MAGICIANBOXBOTTOM", - "S_SLIPTIDEZIP", + "S_WAVEDASH", "S_INSTAWHIP", "S_INSTAWHIP_RECHARGE1", @@ -5547,7 +5547,7 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_MONITOR_SHARD", "MT_MAGICIANBOX", - "MT_SLIPTIDEZIP", + "MT_WAVEDASH", "MT_INSTAWHIP", "MT_INSTAWHIP_RECHARGE", diff --git a/src/g_game.c b/src/g_game.c index 3b4ca5125..687af8a7f 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2243,7 +2243,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) // These are mostly subservient to the player, and may not clean themselves up. PlayerPointerRemove(players[player].followmobj); PlayerPointerRemove(players[player].stumbleIndicator); - PlayerPointerRemove(players[player].sliptideZipIndicator); + PlayerPointerRemove(players[player].wavedashIndicator); PlayerPointerRemove(players[player].trickIndicator); #undef PlayerPointerRemove diff --git a/src/info.c b/src/info.c index a5fc9677d..8e3b38bb9 100644 --- a/src/info.c +++ b/src/info.c @@ -558,7 +558,8 @@ char sprnames[NUMSPRITES + 1][5] = "IMDB", // Item Monitor Small Shard (Debris) "MTWK", // Item Monitor Glass Twinkle - "SLPT", // Sliptide zip indicator + "SLPT", // Wavedash indicator + "TRBS", // Trickdash indicator "IWHP", // Instawhip "WPRE", // Instawhip Recharge @@ -4126,7 +4127,7 @@ state_t states[NUMSTATES] = {SPR_MGBT, FF_FLOORSPRITE|0, -1, {NULL}, 0, 0, S_NULL}, // S_MAGICIANBOX_TOP {SPR_MGBB, FF_FLOORSPRITE|0, -1, {NULL}, 0, 0, S_NULL}, // S_MAGICIANBOX_BOTTOM - {SPR_SLPT, FF_PAPERSPRITE|0, -1, {NULL}, 0, 0, S_NULL}, // S_SLIPTIDEZIP + {SPR_SLPT, FF_PAPERSPRITE|0, -1, {NULL}, 0, 0, S_NULL}, // S_WAVEDASH {SPR_IWHP, FF_FLOORSPRITE|FF_ANIMATE|0, -1, {NULL}, 6, 2, S_NULL}, // S_INSTAWHIP {SPR_NULL, 0, 1, {NULL}, 0, 0, S_INSTAWHIP_RECHARGE2}, // S_INSTAWHIP_RECHARGE1 @@ -23078,9 +23079,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_SLIPTIDEZIP + { // MT_WAVEDASH -1, // doomednum - S_SLIPTIDEZIP, // spawnstate + S_WAVEDASH, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound diff --git a/src/info.h b/src/info.h index 01642bb20..f27c34e85 100644 --- a/src/info.h +++ b/src/info.h @@ -1115,7 +1115,8 @@ typedef enum sprite SPR_IMDB, // Item Monitor Small Shard (Debris) SPR_MTWK, // Item Monitor Glass Twinkle - SPR_SLPT, // Sliptide zip indicator + SPR_SLPT, // Wavedash indicator + SPR_TRBS, // Trickdash indicator SPR_IWHP, // Instawhip SPR_WPRE, // Instawhip Recharge @@ -4537,7 +4538,7 @@ typedef enum state S_MAGICIANBOX_TOP, S_MAGICIANBOX_BOTTOM, - S_SLIPTIDEZIP, + S_WAVEDASH, S_INSTAWHIP, S_INSTAWHIP_RECHARGE1, @@ -6808,7 +6809,7 @@ typedef enum mobj_type MT_MONITOR_PART, MT_MONITOR_SHARD, MT_MAGICIANBOX, - MT_SLIPTIDEZIP, + MT_WAVEDASH, MT_INSTAWHIP, MT_INSTAWHIP_RECHARGE, diff --git a/src/k_kart.c b/src/k_kart.c index 15f0e28f7..ff5d6e34f 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1263,6 +1263,9 @@ static boolean K_HasInfiniteTether(player_t *player) if (player->eggmanexplode > 0) return true; + if (player->trickdash) + return true; + return false; } @@ -1881,9 +1884,9 @@ static void K_SpawnGenericSpeedLines(player_t *player, boolean top) fast->colorized = true; fast->renderflags |= RF_ADD; } - else if (player->sliptideZipBoost) + else if (player->wavedashboost || player->trickdashboost) { - fast->color = SKINCOLOR_WHITE; + fast->color = (player->trickdashboost) ? K_RainbowColor(leveltime) : SKINCOLOR_WHITE; fast->colorized = true; } else if (player->ringboost) @@ -3231,12 +3234,17 @@ static void K_GetKartBoostPower(player_t *player) ); } - if (player->sliptideZipBoost) + if (player->wavedashboost) { - // NB: This is intentionally under the 25% threshold required to initiate a sliptide + // NB: This is intentionally under the 25% handleboost threshold required to initiate a sliptide ADDBOOST(8*FRACUNIT/10, 4*FRACUNIT, 2*SLIPTIDEHANDLING/5); // + 80% top speed, + 400% acceleration, +20% handling } + if (player->trickdashboost) + { + ADDBOOST(8*FRACUNIT/10, 8*FRACUNIT, 3*SLIPTIDEHANDLING/5); // + 80% top speed, + 800% acceleration, +30% handling + } + if (player->spindashboost) // Spindash boost { const fixed_t MAXCHARGESPEED = K_GetSpindashChargeSpeed(player); @@ -4074,7 +4082,7 @@ void K_InitStumbleIndicator(player_t *player) P_SetTarget(&new->target, player->mo); } -void K_InitSliptideZipIndicator(player_t *player) +void K_InitWavedashIndicator(player_t *player) { mobj_t *new = NULL; @@ -4088,14 +4096,14 @@ void K_InitSliptideZipIndicator(player_t *player) return; } - if (P_MobjWasRemoved(player->sliptideZipIndicator) == false) + if (P_MobjWasRemoved(player->wavedashIndicator) == false) { - P_RemoveMobj(player->sliptideZipIndicator); + P_RemoveMobj(player->wavedashIndicator); } - new = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_SLIPTIDEZIP); + new = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_WAVEDASH); - P_SetTarget(&player->sliptideZipIndicator, new); + P_SetTarget(&player->wavedashIndicator, new); P_SetTarget(&new->target, player->mo); } @@ -4250,11 +4258,11 @@ void K_UpdateStumbleIndicator(player_t *player) #define MIN_WAVEDASH_CHARGE ((7*TICRATE/16)*9) -static boolean K_IsLosingSliptideZip(player_t *player) +static boolean K_IsLosingWavedash(player_t *player) { if (player->mo == NULL || P_MobjWasRemoved(player->mo) == true) return true; - if (!K_Sliptiding(player) && player->sliptideZip < MIN_WAVEDASH_CHARGE) + if (!K_Sliptiding(player) && player->wavedash < MIN_WAVEDASH_CHARGE) return true; if (!K_Sliptiding(player) && player->drift == 0 && P_IsObjectOnGround(player->mo) && player->sneakertimer == 0 @@ -4263,7 +4271,7 @@ static boolean K_IsLosingSliptideZip(player_t *player) return false; } -void K_UpdateSliptideZipIndicator(player_t *player) +void K_UpdateWavedashIndicator(player_t *player) { mobj_t *mobj = NULL; @@ -4277,13 +4285,13 @@ void K_UpdateSliptideZipIndicator(player_t *player) return; } - if (player->sliptideZipIndicator == NULL || P_MobjWasRemoved(player->sliptideZipIndicator) == true) + if (player->wavedashIndicator == NULL || P_MobjWasRemoved(player->wavedashIndicator) == true) { - K_InitSliptideZipIndicator(player); + K_InitWavedashIndicator(player); return; } - mobj = player->sliptideZipIndicator; + mobj = player->wavedashIndicator; angle_t momentumAngle = K_MomentumAngle(player->mo); P_MoveOrigin(mobj, player->mo->x - FixedMul(40*mapobjectscale, FINECOSINE(momentumAngle >> ANGLETOFINESHIFT)), @@ -4293,7 +4301,7 @@ void K_UpdateSliptideZipIndicator(player_t *player) P_SetScale(mobj, 3 * player->mo->scale / 2); // No stored boost (or negligible enough that it might be a mistake) - if (player->sliptideZip <= HIDEWAVEDASHCHARGE) + if (player->wavedash <= HIDEWAVEDASHCHARGE) { mobj->renderflags |= RF_DONTDRAW; mobj->frame = 7; @@ -4302,8 +4310,8 @@ void K_UpdateSliptideZipIndicator(player_t *player) mobj->renderflags &= ~RF_DONTDRAW; - UINT32 chargeFrame = 7 - min(7, player->sliptideZip / 100); - UINT32 decayFrame = min(7, player->sliptideZipDelay / 2); + UINT32 chargeFrame = 7 - min(7, player->wavedash / 100); + UINT32 decayFrame = min(7, player->wavedashdelay / 2); if (max(chargeFrame, decayFrame) > mobj->frame) mobj->frame++; else if (max(chargeFrame, decayFrame) < mobj->frame) @@ -4312,7 +4320,7 @@ void K_UpdateSliptideZipIndicator(player_t *player) mobj->renderflags &= ~RF_TRANSMASK; mobj->renderflags |= RF_PAPERSPRITE; - if (K_IsLosingSliptideZip(player)) + if (K_IsLosingWavedash(player)) { // Decay timer's ticking mobj->rollangle += 3*ANG30/4; @@ -4324,6 +4332,17 @@ void K_UpdateSliptideZipIndicator(player_t *player) // Storing boost mobj->rollangle += 3*ANG15/4; } + + if (player->trickdash) + { + mobj->sprite = SPR_TRBS; + mobj->renderflags |= RF_ADD; + } + else + { + mobj->sprite = SPR_SLPT; + mobj->renderflags &= ~RF_ADD; + } } static mobj_t *K_TrickCatholocismBlast(mobj_t *trickIndicator, fixed_t destscale, angle_t rollangle) @@ -8107,7 +8126,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->sneakertimer || player->ringboost || player->driftboost || player->startboost || player->eggmanexplode || player->trickboost - || player->gateBoost || player->sliptideZipBoost) + || player->gateBoost || player->wavedashboost || player->trickdashboost) { #if 0 if (player->invincibilitytimer) @@ -8393,9 +8412,14 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->dropdashboost) player->dropdashboost--; - if (player->sliptideZipBoost > 0 && onground == true) + if (player->wavedashboost > 0 && onground == true) { - player->sliptideZipBoost--; + player->wavedashboost--; + } + + if (player->trickdashboost > 0 && onground == true) + { + player->trickdashboost--; } if (player->spindashboost) @@ -8864,7 +8888,7 @@ void K_KartPlayerAfterThink(player_t *player) K_KartResetPlayerColor(player); K_UpdateStumbleIndicator(player); - K_UpdateSliptideZipIndicator(player); + K_UpdateWavedashIndicator(player); K_UpdateTrickIndicator(player); // Move held objects (Bananas, Orbinaut, etc) @@ -9925,8 +9949,9 @@ static void K_KartDrift(player_t *player, boolean onground) player->drift = player->driftcharge = player->aizdriftstrat = 0; player->pflags &= ~(PF_BRAKEDRIFT|PF_GETSPARKS); // And take away wavedash properties: advanced cornering demands advanced finesse - player->sliptideZip = 0; - player->sliptideZipBoost = 0; + player->wavedash = 0; + player->wavedashboost = 0; + player->trickdashboost = 0; } else if ((player->pflags & PF_DRIFTINPUT) && player->drift != 0) { @@ -10028,11 +10053,11 @@ static void K_KartDrift(player_t *player, boolean onground) || (!player->aizdriftstrat) || (player->steering > 0) != (player->aizdriftstrat > 0)) { - if (!player->drift && player->steering && player->aizdriftstrat && player->sliptideZip // If we were sliptiding last tic, + if (!player->drift && player->steering && player->aizdriftstrat && player->wavedash // If we were sliptiding last tic, && (player->steering > 0) == (player->aizdriftstrat > 0) // we're steering in the right direction, && player->speed >= K_GetKartSpeed(player, false, true)) // and we're above the threshold to spawn dust... { - keepsliptide = true; // Then keep your current sliptide, but note the behavior change for sliptidezip handling. + keepsliptide = true; // Then keep your current sliptide, but note the behavior change for wavedash handling. } else { @@ -10060,9 +10085,9 @@ static void K_KartDrift(player_t *player, boolean onground) // This makes wavedash charge noticeably slower on even modest delay, despite the magnitude of the turn seeming the same. // So we only require 90% of a turn to get full charge strength. - player->sliptideZip += addCharge; + player->wavedash += addCharge; - if (player->sliptideZip >= MIN_WAVEDASH_CHARGE && (player->sliptideZip - addCharge) < MIN_WAVEDASH_CHARGE) + if (player->wavedash >= MIN_WAVEDASH_CHARGE && (player->wavedash - addCharge) < MIN_WAVEDASH_CHARGE) S_StartSound(player->mo, sfx_waved5); } @@ -10088,16 +10113,16 @@ static void K_KartDrift(player_t *player, boolean onground) if (!K_Sliptiding(player) || keepsliptide) { - if (!keepsliptide && K_IsLosingSliptideZip(player) && player->sliptideZip > 0) + if (!keepsliptide && K_IsLosingWavedash(player) && player->wavedash > 0) { - if (player->sliptideZip > HIDEWAVEDASHCHARGE && !S_SoundPlaying(player->mo, sfx_waved2)) + if (player->wavedash > HIDEWAVEDASHCHARGE && !S_SoundPlaying(player->mo, sfx_waved2)) S_StartSoundAtVolume(player->mo, sfx_waved2, 255); // Losing combo time, going to boost S_StopSoundByID(player->mo, sfx_waved1); S_StopSoundByID(player->mo, sfx_waved4); - player->sliptideZipDelay++; - if (player->sliptideZipDelay > TICRATE/2) + player->wavedashdelay++; + if (player->wavedashdelay > TICRATE/2) { - if (player->sliptideZip >= MIN_WAVEDASH_CHARGE) + if (player->wavedash >= MIN_WAVEDASH_CHARGE) { fixed_t maxZipPower = 2*FRACUNIT; fixed_t minZipPower = 1*FRACUNIT; @@ -10112,30 +10137,36 @@ static void K_KartDrift(player_t *player, boolean onground) fixed_t yourPowerReduction = FixedDiv(yourPenalty * FRACUNIT, penaltySpread * FRACUNIT); fixed_t yourPower = maxZipPower - FixedMul(yourPowerReduction, powerSpread); - int yourBoost = FixedInt(FixedMul(yourPower, player->sliptideZip/10 * FRACUNIT)); + int yourBoost = FixedInt(FixedMul(yourPower, player->wavedash/10 * FRACUNIT)); - /* - CONS_Printf("SZ %d MZ %d mZ %d pwS %d mP %d MP %d peS %d yPe %d yPR %d yPw %d yB %d\n", - player->sliptideZip, maxZipPower, minZipPower, powerSpread, minPenalty, maxPenalty, penaltySpread, yourPenalty, yourPowerReduction, yourPower, yourBoost); - */ + if (player->trickdash) + { + player->trickdashboost += 3*yourBoost/2; + S_StartSoundAtVolume(player->mo, sfx_gshba, 255); + } + else + { + player->wavedashboost += yourBoost; + } - player->sliptideZipBoost += yourBoost; + S_StartSoundAtVolume(player->mo, sfx_waved3, 255); // Boost + + player->trickdash = 0; K_SpawnDriftBoostExplosion(player, 0); - S_StartSoundAtVolume(player->mo, sfx_waved3, 255); // Boost } S_StopSoundByID(player->mo, sfx_waved1); S_StopSoundByID(player->mo, sfx_waved2); S_StopSoundByID(player->mo, sfx_waved4); - player->sliptideZip = 0; - player->sliptideZipDelay = 0; + player->wavedash = 0; + player->wavedashdelay = 0; } } else { S_StopSoundByID(player->mo, sfx_waved1); S_StopSoundByID(player->mo, sfx_waved2); - if (player->sliptideZip > 0 && !S_SoundPlaying(player->mo, sfx_waved4)) + if (player->wavedash > 0 && !S_SoundPlaying(player->mo, sfx_waved4)) S_StartSoundAtVolume(player->mo, sfx_waved4, 255); // Passive woosh } @@ -10149,10 +10180,10 @@ static void K_KartDrift(player_t *player, boolean onground) } else { - player->sliptideZipDelay = 0; + player->wavedashdelay = 0; S_StopSoundByID(player->mo, sfx_waved2); S_StopSoundByID(player->mo, sfx_waved4); - if (player->sliptideZip > HIDEWAVEDASHCHARGE && !S_SoundPlaying(player->mo, sfx_waved1)) + if (player->wavedash > HIDEWAVEDASHCHARGE && !S_SoundPlaying(player->mo, sfx_waved1)) S_StartSoundAtVolume(player->mo, sfx_waved1, 255); // Charging } @@ -10711,7 +10742,7 @@ static void K_KartSpindashWind(mobj_t *parent) P_SetTarget(&wind->target, parent); - if (parent->player && parent->player->sliptideZipBoost) + if (parent->player && parent->player->wavedashboost) P_SetScale(wind, wind->scale * 2); if (parent->momx || parent->momy) @@ -10775,7 +10806,7 @@ static void K_KartSpindash(player_t *player) K_KartSpindashWind(player->mo); } - if ((player->sliptideZipBoost > 0) && (spawnWind == true)) + if ((player->wavedashboost > 0 || player->trickdashboost > 0) && (spawnWind == true)) { K_KartSpindashWind(player->mo); } @@ -11885,7 +11916,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) if (player->throwdir == -1) { P_InstaThrust(player->mo, player->mo->angle, player->speed + (80 * mapobjectscale)); - player->sliptideZipBoost += TICRATE; // Just for keeping speed briefly vs. tripwire etc. + player->wavedashboost += TICRATE; // Just for keeping speed briefly vs. tripwire etc. // If this doesn't turn out to be reliable, I'll change it to directly set leniency or something. } K_PlayAttackTaunt(player->mo); @@ -12218,6 +12249,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) { S_StartSound(player->mo, sfx_trick0); player->dotrickfx = true; + player->trickboostdecay = min(TICRATE*3/4, abs(momz/FRACUNIT)); if (cmd->turning > 0) { @@ -12252,6 +12284,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) { S_StartSound(player->mo, sfx_trick0); player->dotrickfx = true; + player->trickboostdecay = min(TICRATE*3/4, abs(momz/FRACUNIT)); if (cmd->throwdir > 0) // forward trick { @@ -12366,24 +12399,31 @@ void K_MoveKartPlayer(player_t *player, boolean onground) } else if ((player->trickpanel != TRICKSTATE_NONE) && P_IsObjectOnGround(player->mo)) // Landed from trick { + K_SpawnDashDustRelease(player); + if (player->fastfall) { + P_InstaThrust(player->mo, player->mo->angle, 2*abs(player->fastfall)/3 + 15*FRACUNIT); player->mo->hitlag = 3; - K_SpawnDashDustRelease(player); - P_InstaThrust(player->mo, player->mo->angle, 30*FRACUNIT); - S_StartSound(player->mo, sfx_gshce); + S_StartSound(player->mo, sfx_gshac); // TODO player->fastfall = 0; // intentionally skip bounce } - - if (player->trickpanel == TRICKSTATE_BACK) // upward trick + else { S_StartSound(player->mo, sfx_s23c); K_SpawnDashDustRelease(player); player->trickboost = TICRATE - player->trickboostdecay; - } + player->wavedash += 150; // bonus for the slow fall + //player->wavedashdelay = TICRATE/2 - 2; + player->wavedashdelay = 0; - player->sliptideZip += 300; - player->sliptideZipDelay = 0; + if (player->trickpanel == TRICKSTATE_FORWARD) + player->trickboostpower /= 18; + else if (player->trickpanel != TRICKSTATE_BACK) + player->trickboostpower /= 9; + + player->trickdash = true; + } player->trickpanel = TRICKSTATE_NONE; player->trickboostdecay = 0; diff --git a/src/k_kart.h b/src/k_kart.h index 3f6293bba..d5782e550 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -119,10 +119,10 @@ angle_t K_StumbleSlope(angle_t angle, angle_t pitch, angle_t roll); void K_StumblePlayer(player_t *player); boolean K_CheckStumble(player_t *player, angle_t oldPitch, angle_t oldRoll, boolean fromAir); void K_InitStumbleIndicator(player_t *player); -void K_InitSliptideZipIndicator(player_t *player); +void K_InitWavedashIndicator(player_t *player); void K_InitTrickIndicator(player_t *player); void K_UpdateStumbleIndicator(player_t *player); -void K_UpdateSliptideZipIndicator(player_t *player); +void K_UpdateWavedashIndicator(player_t *player); void K_UpdateTrickIndicator(player_t *player); INT32 K_ExplodePlayer(player_t *player, mobj_t *inflictor, mobj_t *source); void K_DebtStingPlayer(player_t *player, mobj_t *source); diff --git a/src/k_respawn.c b/src/k_respawn.c index 21af8253d..107e7c7ed 100644 --- a/src/k_respawn.c +++ b/src/k_respawn.c @@ -156,7 +156,8 @@ void K_DoIngameRespawn(player_t *player) player->ringboost = 0; player->driftboost = player->strongdriftboost = 0; player->gateBoost = 0; - player->sliptideZip = player->sliptideZipBoost = player->sliptideZipDelay = 0; + player->trickdash = 0; + player->wavedash = player->wavedashboost = player->wavedashdelay = player->trickdashboost = 0; K_TumbleInterrupt(player); P_ResetPlayer(player); diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 0bda04838..6314665b9 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -325,12 +325,16 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->tripwireLeniency); else if (fastcmp(field,"tripwireReboundDelay")) lua_pushinteger(L, plr->tripwireReboundDelay); - else if (fastcmp(field,"sliptideZip")) - lua_pushinteger(L, plr->sliptideZip); - else if (fastcmp(field,"sliptideZipDelay")) - lua_pushinteger(L, plr->sliptideZipDelay); - else if (fastcmp(field,"sliptideZipBoost")) - lua_pushinteger(L, plr->sliptideZipBoost); + else if (fastcmp(field,"wavedash")) + lua_pushinteger(L, plr->wavedash); + else if (fastcmp(field,"wavedashdelay")) + lua_pushinteger(L, plr->wavedashdelay); + else if (fastcmp(field,"wavedashboost")) + lua_pushinteger(L, plr->wavedashboost); + else if (fastcmp(field,"trickdashboost")) + lua_pushinteger(L, plr->trickdashboost); + else if (fastcmp(field,"trickdash")) + lua_pushinteger(L, plr->trickdash); else if (fastcmp(field,"lastsafelap")) lua_pushinteger(L, plr->lastsafelap); else if (fastcmp(field,"instaWhipCharge")) @@ -809,12 +813,16 @@ static int player_set(lua_State *L) plr->tripwireLeniency = luaL_checkinteger(L, 3); else if (fastcmp(field,"tripwireReboundDelay")) plr->tripwireReboundDelay = luaL_checkinteger(L, 3); - else if (fastcmp(field,"sliptideZip")) - plr->sliptideZip = luaL_checkinteger(L, 3); - else if (fastcmp(field,"sliptideZipDelay")) - plr->sliptideZipDelay = luaL_checkinteger(L, 3); - else if (fastcmp(field,"sliptideZipBoost")) - plr->sliptideZipBoost = luaL_checkinteger(L, 3); + else if (fastcmp(field,"wavedash")) + plr->wavedash = luaL_checkinteger(L, 3); + else if (fastcmp(field,"wavedashdelay")) + plr->wavedashdelay = luaL_checkinteger(L, 3); + else if (fastcmp(field,"wavedashboost")) + plr->wavedashboost = luaL_checkinteger(L, 3); + else if (fastcmp(field,"trickdashboost")) + plr->trickdashboost = luaL_checkinteger(L, 3); + else if (fastcmp(field,"trickdash")) + plr->trickdash = luaL_checkinteger(L, 3); else if (fastcmp(field,"lastsafelap")) plr->lastsafelap = luaL_checkinteger(L, 3); else if (fastcmp(field,"instaWhipCharge")) diff --git a/src/p_inter.c b/src/p_inter.c index fc7458ad6..2d1f7b0ff 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2558,7 +2558,7 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, } PlayerPointerRemove(player->stumbleIndicator); - PlayerPointerRemove(player->sliptideZipIndicator); + PlayerPointerRemove(player->wavedashIndicator); PlayerPointerRemove(player->trickIndicator); #undef PlayerPointerRemove diff --git a/src/p_mobj.c b/src/p_mobj.c index efb668fec..565647cb7 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -12543,7 +12543,7 @@ void P_SpawnPlayer(INT32 playernum) p->griefValue = 0; K_InitStumbleIndicator(p); - K_InitSliptideZipIndicator(p); + K_InitWavedashIndicator(p); K_InitTrickIndicator(p); if (gametyperules & GTR_ITEMARROWS) diff --git a/src/p_saveg.c b/src/p_saveg.c index 1860b84e8..f86cf2c3d 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -75,7 +75,7 @@ typedef enum SKYBOXCENTER = 0x0010, HOVERHYUDORO = 0x0020, STUMBLE = 0x0040, - SLIPTIDEZIP = 0x0080, + WAVEDASH = 0x0080, RINGSHOOTER = 0x0100, WHIP = 0x0200, HAND = 0x0400, @@ -311,8 +311,8 @@ static void P_NetArchivePlayers(savebuffer_t *save) if (players[i].stumbleIndicator) flags |= STUMBLE; - if (players[i].sliptideZipIndicator) - flags |= SLIPTIDEZIP; + if (players[i].wavedashIndicator) + flags |= WAVEDASH; if (players[i].trickIndicator) flags |= TRICKINDICATOR; @@ -352,8 +352,8 @@ static void P_NetArchivePlayers(savebuffer_t *save) if (flags & STUMBLE) WRITEUINT32(save->p, players[i].stumbleIndicator->mobjnum); - if (flags & SLIPTIDEZIP) - WRITEUINT32(save->p, players[i].sliptideZipIndicator->mobjnum); + if (flags & WAVEDASH) + WRITEUINT32(save->p, players[i].wavedashIndicator->mobjnum); if (flags & TRICKINDICATOR) WRITEUINT32(save->p, players[i].trickIndicator->mobjnum); @@ -542,9 +542,11 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEUINT8(save->p, players[i].tripwireReboundDelay); - WRITEUINT16(save->p, players[i].sliptideZip); - WRITEUINT8(save->p, players[i].sliptideZipDelay); - WRITEUINT16(save->p, players[i].sliptideZipBoost); + WRITEUINT16(save->p, players[i].wavedash); + WRITEUINT8(save->p, players[i].wavedashdelay); + WRITEUINT16(save->p, players[i].wavedashboost); + WRITEUINT8(save->p, players[i].trickdash); + WRITEUINT16(save->p, players[i].trickdashboost); WRITEUINT8(save->p, players[i].lastsafelap); @@ -869,8 +871,8 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) if (flags & STUMBLE) players[i].stumbleIndicator = (mobj_t *)(size_t)READUINT32(save->p); - if (flags & SLIPTIDEZIP) - players[i].sliptideZipIndicator = (mobj_t *)(size_t)READUINT32(save->p); + if (flags & WAVEDASH) + players[i].wavedashIndicator = (mobj_t *)(size_t)READUINT32(save->p); if (flags & TRICKINDICATOR) players[i].trickIndicator = (mobj_t *)(size_t)READUINT32(save->p); @@ -1060,9 +1062,11 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].tripwireReboundDelay = READUINT8(save->p); - players[i].sliptideZip = READUINT16(save->p); - players[i].sliptideZipDelay = READUINT8(save->p); - players[i].sliptideZipBoost = READUINT16(save->p); + players[i].wavedash = READUINT16(save->p); + players[i].wavedashdelay = READUINT8(save->p); + players[i].wavedashboost = READUINT16(save->p); + players[i].trickdash = READUINT8(save->p); + players[i].trickdashboost = READUINT16(save->p); players[i].lastsafelap = READUINT8(save->p); @@ -5600,12 +5604,12 @@ static void P_RelinkPointers(void) if (!P_SetTarget(&players[i].stumbleIndicator, P_FindNewPosition(temp))) CONS_Debug(DBG_GAMELOGIC, "stumbleIndicator not found on player %d\n", i); } - if (players[i].sliptideZipIndicator) + if (players[i].wavedashIndicator) { - temp = (UINT32)(size_t)players[i].sliptideZipIndicator; - players[i].sliptideZipIndicator = NULL; - if (!P_SetTarget(&players[i].sliptideZipIndicator, P_FindNewPosition(temp))) - CONS_Debug(DBG_GAMELOGIC, "sliptideZipIndicator not found on player %d\n", i); + temp = (UINT32)(size_t)players[i].wavedashIndicator; + players[i].wavedashIndicator = NULL; + if (!P_SetTarget(&players[i].wavedashIndicator, P_FindNewPosition(temp))) + CONS_Debug(DBG_GAMELOGIC, "wavedashIndicator not found on player %d\n", i); } if (players[i].trickIndicator) { diff --git a/src/p_user.c b/src/p_user.c index 81a5cd555..ef505d934 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4000,7 +4000,7 @@ void P_PlayerThink(player_t *player) PlayerPointerErase(player->followmobj); PlayerPointerErase(player->stumbleIndicator); - PlayerPointerErase(player->sliptideZipIndicator); + PlayerPointerErase(player->wavedashIndicator); PlayerPointerErase(player->trickIndicator); PlayerPointerErase(player->whip); PlayerPointerErase(player->hand); From c11394ce835006a31f9c71e5f5c4d3807e7a1a65 Mon Sep 17 00:00:00 2001 From: AJ Martinez Date: Thu, 9 Nov 2023 00:45:50 -0700 Subject: [PATCH 26/37] WIP: Trick panel decrackening --- src/d_player.h | 6 ++++-- src/k_kart.c | 47 +++++++++++++++++++++++++++++++++++++++------ src/k_respawn.c | 1 + src/lua_playerlib.c | 20 +++++++++++-------- src/p_saveg.c | 2 ++ 5 files changed, 60 insertions(+), 16 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index bd951e7c7..a021290cf 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -898,8 +898,10 @@ struct player_t UINT16 wavedash; // How long is our chained sliptide? Grant a proportional boost when it's over. UINT8 wavedashdelay; // How long since the last sliptide? Only boost once you've been straightened out for a bit. UINT16 wavedashboost; // The actual boost granted from wavedash. - UINT16 trickdashboost; // The actual boost granted from wavedash. - boolean trickdash; + UINT16 trickdashboost; // Trickdashes grant a snappier boost that permits sliptide. [UNUSED, TOO MUCH CRACK] + boolean trickdash; // Is the wavedash we're charging right now getting upgraded to a trickdash? [UNUSED] + + UINT16 trickcharge; // Landed normally from a trick panel? Get the benefits package! UINT8 lastsafelap; diff --git a/src/k_kart.c b/src/k_kart.c index ff5d6e34f..e212dc6ae 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1266,6 +1266,9 @@ static boolean K_HasInfiniteTether(player_t *player) if (player->trickdash) return true; + if (player->trickcharge) + return true; + return false; } @@ -3245,6 +3248,11 @@ static void K_GetKartBoostPower(player_t *player) ADDBOOST(8*FRACUNIT/10, 8*FRACUNIT, 3*SLIPTIDEHANDLING/5); // + 80% top speed, + 800% acceleration, +30% handling } + if (player->trickcharge) + { + ADDBOOST(0, 0, 2*SLIPTIDEHANDLING/10); // 0% speed 0% accel 20% handle + } + if (player->spindashboost) // Spindash boost { const fixed_t MAXCHARGESPEED = K_GetSpindashChargeSpeed(player); @@ -8422,6 +8430,13 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) player->trickdashboost--; } + if (player->trickcharge > 0 && onground == true) + { + player->trickcharge--; + if (player->drift) + player->trickcharge = max(player->trickcharge, 1); + } + if (player->spindashboost) { player->spindashboost--; @@ -8853,6 +8868,14 @@ void K_KartResetPlayerColor(player_t *player) } } + if (player->trickcharge && (leveltime & 1)) + { + player->mo->colorized = true; + player->mo->color = SKINCOLOR_INVINCFLASH; + fullbright = true; + goto finalise; + } + if (player->ringboost && (leveltime & 1)) // ring boosting { player->mo->colorized = true; @@ -9899,6 +9922,15 @@ static void K_KartDrift(player_t *player, boolean onground) K_SpawnDriftBoostExplosion(player, 4); K_SpawnDriftElectricSparks(player, K_DriftSparkColor(player, player->driftcharge), false); } + + if (player->trickcharge) + { + player->driftboost += 20; + player->wavedashboost += 10; + P_Thrust(player->mo, pushdir, player->speed / 2); + S_StartSound(player->mo, sfx_gshba); + player->trickcharge = 0; + } } // Remove charge @@ -10017,6 +10049,9 @@ static void K_KartDrift(player_t *player, boolean onground) driftadditive = 0; } + if (player->trickcharge && driftadditive) + driftadditive += 24; + // This spawns the drift sparks if ((player->driftcharge + driftadditive >= dsone) || (player->driftcharge < 0)) @@ -12412,17 +12447,17 @@ void K_MoveKartPlayer(player_t *player, boolean onground) { S_StartSound(player->mo, sfx_s23c); K_SpawnDashDustRelease(player); - player->trickboost = TICRATE - player->trickboostdecay; - player->wavedash += 150; // bonus for the slow fall - //player->wavedashdelay = TICRATE/2 - 2; - player->wavedashdelay = 0; + + UINT8 award = TICRATE - player->trickboostdecay; + + //player->trickboost = award; + player->trickcharge += award*4; + K_AwardPlayerRings(player, award/2, true); if (player->trickpanel == TRICKSTATE_FORWARD) player->trickboostpower /= 18; else if (player->trickpanel != TRICKSTATE_BACK) player->trickboostpower /= 9; - - player->trickdash = true; } player->trickpanel = TRICKSTATE_NONE; diff --git a/src/k_respawn.c b/src/k_respawn.c index 107e7c7ed..f7873e90a 100644 --- a/src/k_respawn.c +++ b/src/k_respawn.c @@ -157,6 +157,7 @@ void K_DoIngameRespawn(player_t *player) player->driftboost = player->strongdriftboost = 0; player->gateBoost = 0; player->trickdash = 0; + player->trickcharge = 0; player->wavedash = player->wavedashboost = player->wavedashdelay = player->trickdashboost = 0; K_TumbleInterrupt(player); diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 6314665b9..d77880391 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -331,10 +331,12 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->wavedashdelay); else if (fastcmp(field,"wavedashboost")) lua_pushinteger(L, plr->wavedashboost); - else if (fastcmp(field,"trickdashboost")) - lua_pushinteger(L, plr->trickdashboost); - else if (fastcmp(field,"trickdash")) - lua_pushinteger(L, plr->trickdash); + else if (fastcmp(field,"trickcharge")) + lua_pushinteger(L, plr->trickcharge); + //else if (fastcmp(field,"trickdashboost")) + // lua_pushinteger(L, plr->trickdashboost); + //else if (fastcmp(field,"trickdash")) + // lua_pushinteger(L, plr->trickdash); else if (fastcmp(field,"lastsafelap")) lua_pushinteger(L, plr->lastsafelap); else if (fastcmp(field,"instaWhipCharge")) @@ -819,10 +821,12 @@ static int player_set(lua_State *L) plr->wavedashdelay = luaL_checkinteger(L, 3); else if (fastcmp(field,"wavedashboost")) plr->wavedashboost = luaL_checkinteger(L, 3); - else if (fastcmp(field,"trickdashboost")) - plr->trickdashboost = luaL_checkinteger(L, 3); - else if (fastcmp(field,"trickdash")) - plr->trickdash = luaL_checkinteger(L, 3); + else if (fastcmp(field,"trickcharge")) + plr->trickcharge = luaL_checkinteger(L, 3); + //else if (fastcmp(field,"trickdashboost")) + // plr->trickdashboost = luaL_checkinteger(L, 3); + //else if (fastcmp(field,"trickdash")) + // plr->trickdash = luaL_checkinteger(L, 3); else if (fastcmp(field,"lastsafelap")) plr->lastsafelap = luaL_checkinteger(L, 3); else if (fastcmp(field,"instaWhipCharge")) diff --git a/src/p_saveg.c b/src/p_saveg.c index f86cf2c3d..30668eb3f 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -547,6 +547,7 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEUINT16(save->p, players[i].wavedashboost); WRITEUINT8(save->p, players[i].trickdash); WRITEUINT16(save->p, players[i].trickdashboost); + WRITEUINT16(save->p, players[i].trickcharge); WRITEUINT8(save->p, players[i].lastsafelap); @@ -1067,6 +1068,7 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].wavedashboost = READUINT16(save->p); players[i].trickdash = READUINT8(save->p); players[i].trickdashboost = READUINT16(save->p); + players[i].trickcharge = READUINT16(save->p); players[i].lastsafelap = READUINT8(save->p); From 19edcbe9c2333e1863ac33c0d57e06d66f31abd7 Mon Sep 17 00:00:00 2001 From: AJ Martinez Date: Thu, 9 Nov 2023 02:02:41 -0700 Subject: [PATCH 27/37] WIP: Trickpanel crack IV --- src/d_player.h | 4 +-- src/k_kart.c | 84 ++++++++++++++++++--------------------------- src/k_respawn.c | 4 +-- src/lua_playerlib.c | 12 +++---- src/p_saveg.c | 8 ++--- 5 files changed, 45 insertions(+), 67 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index a021290cf..d31874e76 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -898,11 +898,11 @@ struct player_t UINT16 wavedash; // How long is our chained sliptide? Grant a proportional boost when it's over. UINT8 wavedashdelay; // How long since the last sliptide? Only boost once you've been straightened out for a bit. UINT16 wavedashboost; // The actual boost granted from wavedash. - UINT16 trickdashboost; // Trickdashes grant a snappier boost that permits sliptide. [UNUSED, TOO MUCH CRACK] - boolean trickdash; // Is the wavedash we're charging right now getting upgraded to a trickdash? [UNUSED] UINT16 trickcharge; // Landed normally from a trick panel? Get the benefits package! + UINT16 infinitether; // Generic infinitether time, used for infinitether leniency. + UINT8 lastsafelap; mobj_t *stumbleIndicator; diff --git a/src/k_kart.c b/src/k_kart.c index e212dc6ae..904ed2b56 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1263,10 +1263,10 @@ static boolean K_HasInfiniteTether(player_t *player) if (player->eggmanexplode > 0) return true; - if (player->trickdash) + if (player->trickcharge) return true; - if (player->trickcharge) + if (player->infinitether) return true; return false; @@ -1887,9 +1887,9 @@ static void K_SpawnGenericSpeedLines(player_t *player, boolean top) fast->colorized = true; fast->renderflags |= RF_ADD; } - else if (player->wavedashboost || player->trickdashboost) + else if (player->wavedashboost) { - fast->color = (player->trickdashboost) ? K_RainbowColor(leveltime) : SKINCOLOR_WHITE; + fast->color = SKINCOLOR_WHITE; fast->colorized = true; } else if (player->ringboost) @@ -3243,14 +3243,9 @@ static void K_GetKartBoostPower(player_t *player) ADDBOOST(8*FRACUNIT/10, 4*FRACUNIT, 2*SLIPTIDEHANDLING/5); // + 80% top speed, + 400% acceleration, +20% handling } - if (player->trickdashboost) - { - ADDBOOST(8*FRACUNIT/10, 8*FRACUNIT, 3*SLIPTIDEHANDLING/5); // + 80% top speed, + 800% acceleration, +30% handling - } - if (player->trickcharge) { - ADDBOOST(0, 0, 2*SLIPTIDEHANDLING/10); // 0% speed 0% accel 20% handle + ADDBOOST(0, FRACUNIT, 2*SLIPTIDEHANDLING/10); // 0% speed 100% accel 20% handle } if (player->spindashboost) // Spindash boost @@ -4340,17 +4335,6 @@ void K_UpdateWavedashIndicator(player_t *player) // Storing boost mobj->rollangle += 3*ANG15/4; } - - if (player->trickdash) - { - mobj->sprite = SPR_TRBS; - mobj->renderflags |= RF_ADD; - } - else - { - mobj->sprite = SPR_SLPT; - mobj->renderflags &= ~RF_ADD; - } } static mobj_t *K_TrickCatholocismBlast(mobj_t *trickIndicator, fixed_t destscale, angle_t rollangle) @@ -8134,7 +8118,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->sneakertimer || player->ringboost || player->driftboost || player->startboost || player->eggmanexplode || player->trickboost - || player->gateBoost || player->wavedashboost || player->trickdashboost) + || player->gateBoost || player->wavedashboost) { #if 0 if (player->invincibilitytimer) @@ -8425,11 +8409,6 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) player->wavedashboost--; } - if (player->trickdashboost > 0 && onground == true) - { - player->trickdashboost--; - } - if (player->trickcharge > 0 && onground == true) { player->trickcharge--; @@ -8437,6 +8416,11 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) player->trickcharge = max(player->trickcharge, 1); } + if (player->infinitether > 0) + { + player->infinitether--; + } + if (player->spindashboost) { player->spindashboost--; @@ -8549,6 +8533,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->dotrickfx && !player->mo->hitlag) { S_StartSound(player->mo, sfx_trick1); + player->trickcharge = 8*TICRATE; player->dotrickfx = false; } @@ -9845,6 +9830,8 @@ static void K_KartDrift(player_t *player, boolean onground) const UINT16 buttons = K_GetKartButtons(player); + boolean dokicker = false; + // Drifting is actually straffing + automatic turning. // Holding the Jump button will enable drifting. // (This comment is extremely funny) @@ -9907,6 +9894,7 @@ static void K_KartDrift(player_t *player, boolean onground) K_SpawnDriftBoostExplosion(player, 3); K_SpawnDriftElectricSparks(player, K_DriftSparkColor(player, player->driftcharge), false); + dokicker = true; } else if (player->driftcharge >= dsfour) { @@ -9921,15 +9909,17 @@ static void K_KartDrift(player_t *player, boolean onground) K_SpawnDriftBoostExplosion(player, 4); K_SpawnDriftElectricSparks(player, K_DriftSparkColor(player, player->driftcharge), false); + dokicker = true; } - if (player->trickcharge) + if (player->trickcharge && dokicker) { player->driftboost += 20; player->wavedashboost += 10; P_Thrust(player->mo, pushdir, player->speed / 2); S_StartSound(player->mo, sfx_gshba); player->trickcharge = 0; + player->infinitether = TICRATE*2; } } @@ -9983,7 +9973,6 @@ static void K_KartDrift(player_t *player, boolean onground) // And take away wavedash properties: advanced cornering demands advanced finesse player->wavedash = 0; player->wavedashboost = 0; - player->trickdashboost = 0; } else if ((player->pflags & PF_DRIFTINPUT) && player->drift != 0) { @@ -10050,7 +10039,7 @@ static void K_KartDrift(player_t *player, boolean onground) } if (player->trickcharge && driftadditive) - driftadditive += 24; + driftadditive += 16; // This spawns the drift sparks if ((player->driftcharge + driftadditive >= dsone) @@ -10174,20 +10163,10 @@ static void K_KartDrift(player_t *player, boolean onground) fixed_t yourPower = maxZipPower - FixedMul(yourPowerReduction, powerSpread); int yourBoost = FixedInt(FixedMul(yourPower, player->wavedash/10 * FRACUNIT)); - if (player->trickdash) - { - player->trickdashboost += 3*yourBoost/2; - S_StartSoundAtVolume(player->mo, sfx_gshba, 255); - } - else - { - player->wavedashboost += yourBoost; - } + player->wavedashboost += yourBoost; S_StartSoundAtVolume(player->mo, sfx_waved3, 255); // Boost - player->trickdash = 0; - K_SpawnDriftBoostExplosion(player, 0); } S_StopSoundByID(player->mo, sfx_waved1); @@ -10841,7 +10820,7 @@ static void K_KartSpindash(player_t *player) K_KartSpindashWind(player->mo); } - if ((player->wavedashboost > 0 || player->trickdashboost > 0) && (spawnWind == true)) + if ((player->wavedashboost > 0) && (spawnWind == true)) { K_KartSpindashWind(player->mo); } @@ -12284,6 +12263,10 @@ void K_MoveKartPlayer(player_t *player, boolean onground) { S_StartSound(player->mo, sfx_trick0); player->dotrickfx = true; + + // Calculate speed boost decay: + // Base speed boost duration is 35 tics. + // At most, lose 3/4th of your boost. player->trickboostdecay = min(TICRATE*3/4, abs(momz/FRACUNIT)); if (cmd->turning > 0) @@ -12319,10 +12302,15 @@ void K_MoveKartPlayer(player_t *player, boolean onground) { S_StartSound(player->mo, sfx_trick0); player->dotrickfx = true; + + // Calculate speed boost decay: + // Base speed boost duration is 35 tics. + // At most, lose 3/4th of your boost. player->trickboostdecay = min(TICRATE*3/4, abs(momz/FRACUNIT)); if (cmd->throwdir > 0) // forward trick { + if (player->mo->momz * P_MobjFlip(player->mo) > 0) { player->mo->momz = 0; @@ -12348,12 +12336,6 @@ void K_MoveKartPlayer(player_t *player, boolean onground) player->mo->momz = 0; // relative = false; } - // Calculate speed boost decay: - // Base speed boost duration is 35 tics. - // At most, lose 3/4th of your boost. - player->trickboostdecay = min(TICRATE*3/4, abs(momz/FRACUNIT)); - //CONS_Printf("decay: %d\n", player->trickboostdecay); - player->mo->momz += P_MobjFlip(player->mo)*48*mapobjectscale; player->trickpanel = TRICKSTATE_BACK; @@ -12442,6 +12424,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) player->mo->hitlag = 3; S_StartSound(player->mo, sfx_gshac); // TODO player->fastfall = 0; // intentionally skip bounce + player->trickcharge = 0; } else { @@ -12450,9 +12433,8 @@ void K_MoveKartPlayer(player_t *player, boolean onground) UINT8 award = TICRATE - player->trickboostdecay; - //player->trickboost = award; - player->trickcharge += award*4; - K_AwardPlayerRings(player, award/2, true); + player->trickboost = award; + K_AwardPlayerRings(player, award, true); if (player->trickpanel == TRICKSTATE_FORWARD) player->trickboostpower /= 18; diff --git a/src/k_respawn.c b/src/k_respawn.c index f7873e90a..946a62c08 100644 --- a/src/k_respawn.c +++ b/src/k_respawn.c @@ -156,9 +156,9 @@ void K_DoIngameRespawn(player_t *player) player->ringboost = 0; player->driftboost = player->strongdriftboost = 0; player->gateBoost = 0; - player->trickdash = 0; player->trickcharge = 0; - player->wavedash = player->wavedashboost = player->wavedashdelay = player->trickdashboost = 0; + player->infinitether = 0; + player->wavedash = player->wavedashboost = player->wavedashdelay = 0; K_TumbleInterrupt(player); P_ResetPlayer(player); diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index d77880391..48f5739e2 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -333,10 +333,8 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->wavedashboost); else if (fastcmp(field,"trickcharge")) lua_pushinteger(L, plr->trickcharge); - //else if (fastcmp(field,"trickdashboost")) - // lua_pushinteger(L, plr->trickdashboost); - //else if (fastcmp(field,"trickdash")) - // lua_pushinteger(L, plr->trickdash); + else if (fastcmp(field,"infinitether")) + lua_pushinteger(L, plr->infinitether); else if (fastcmp(field,"lastsafelap")) lua_pushinteger(L, plr->lastsafelap); else if (fastcmp(field,"instaWhipCharge")) @@ -823,10 +821,8 @@ static int player_set(lua_State *L) plr->wavedashboost = luaL_checkinteger(L, 3); else if (fastcmp(field,"trickcharge")) plr->trickcharge = luaL_checkinteger(L, 3); - //else if (fastcmp(field,"trickdashboost")) - // plr->trickdashboost = luaL_checkinteger(L, 3); - //else if (fastcmp(field,"trickdash")) - // plr->trickdash = luaL_checkinteger(L, 3); + else if (fastcmp(field,"infinitether")) + plr->infinitether = luaL_checkinteger(L, 3); else if (fastcmp(field,"lastsafelap")) plr->lastsafelap = luaL_checkinteger(L, 3); else if (fastcmp(field,"instaWhipCharge")) diff --git a/src/p_saveg.c b/src/p_saveg.c index 30668eb3f..5f89f86db 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -545,10 +545,10 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEUINT16(save->p, players[i].wavedash); WRITEUINT8(save->p, players[i].wavedashdelay); WRITEUINT16(save->p, players[i].wavedashboost); - WRITEUINT8(save->p, players[i].trickdash); - WRITEUINT16(save->p, players[i].trickdashboost); WRITEUINT16(save->p, players[i].trickcharge); + WRITEUINT16(save->p, players[i].infinitether); + WRITEUINT8(save->p, players[i].lastsafelap); WRITEMEM(save->p, players[i].public_key, PUBKEYLENGTH); @@ -1066,10 +1066,10 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].wavedash = READUINT16(save->p); players[i].wavedashdelay = READUINT8(save->p); players[i].wavedashboost = READUINT16(save->p); - players[i].trickdash = READUINT8(save->p); - players[i].trickdashboost = READUINT16(save->p); players[i].trickcharge = READUINT16(save->p); + players[i].infinitether = READUINT16(save->p); + players[i].lastsafelap = READUINT8(save->p); READMEM(save->p, players[i].public_key, PUBKEYLENGTH); From e20218a9d6722758510b4b97d69ee37bc7cf29ed Mon Sep 17 00:00:00 2001 From: AJ Martinez Date: Sun, 12 Nov 2023 03:38:17 -0700 Subject: [PATCH 28/37] Trick Charge VFX WIP --- src/deh_tables.c | 4 ++++ src/info.c | 31 +++++++++++++++++++++++++++++++ src/info.h | 6 ++++++ src/k_kart.c | 15 +++++++++++++++ src/k_objects.h | 2 ++ src/objects/CMakeLists.txt | 1 + src/objects/charge.c | 34 ++++++++++++++++++++++++++++++++++ src/p_mobj.c | 5 +++++ 8 files changed, 98 insertions(+) create mode 100644 src/objects/charge.c diff --git a/src/deh_tables.c b/src/deh_tables.c index c0d35b1b5..4b11f9421 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -3325,6 +3325,8 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_BLOCKRING", "S_BLOCKBODY", + "S_CHARGEAURA", + "S_SERVANTHAND", "S_HORNCODE", @@ -5555,6 +5557,8 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_BLOCKRING", "MT_BLOCKBODY", + "MT_CHARGEAURA", + "MT_SERVANTHAND", "MT_HORNCODE", diff --git a/src/info.c b/src/info.c index 8e3b38bb9..4e93c7473 100644 --- a/src/info.c +++ b/src/info.c @@ -567,6 +567,8 @@ char sprnames[NUMSPRITES + 1][5] = "GRNG", // Guard ring "GBDY", // Guard body + "TRC1", // Charge aura + "DHND", // Servant Hand "HORN", // Horncode @@ -4138,6 +4140,8 @@ state_t states[NUMSTATES] = {SPR_GRNG, FF_FULLBRIGHT|FF_PAPERSPRITE|0, -1, {NULL}, 0, 0, S_NULL}, // S_BLOCKRING {SPR_GBDY, FF_FULLBRIGHT|FF_ANIMATE|0, -1, {NULL}, 4, 2, S_NULL}, // S_BLOCKBODY + {SPR_TRC1, FF_FULLBRIGHT|FF_ANIMATE|0, -1, {NULL}, 4, 2, S_NULL}, // S_CHARGEAURA + {SPR_DHND, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SERVANTHAND {SPR_HORN, 0, -1, {NULL}, 0, 0, S_NULL}, // S_HORNCODE @@ -23241,6 +23245,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_CHARGEAURA + -1, // doomednum + S_CHARGEAURA, // 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 + 67*FRACUNIT, // radius + 67*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + { // MT_SERVANTHAND -1, // doomednum S_SERVANTHAND, // spawnstate diff --git a/src/info.h b/src/info.h index f27c34e85..54cb2ed75 100644 --- a/src/info.h +++ b/src/info.h @@ -1124,6 +1124,8 @@ typedef enum sprite SPR_GRNG, // Guard ring SPR_GBDY, // Guard body + SPR_TRC1, // Charge aura + SPR_DHND, // Servant Hand SPR_HORN, // Horncode @@ -4549,6 +4551,8 @@ typedef enum state S_BLOCKRING, S_BLOCKBODY, + S_CHARGEAURA, + S_SERVANTHAND, S_HORNCODE, @@ -6817,6 +6821,8 @@ typedef enum mobj_type MT_BLOCKRING, MT_BLOCKBODY, + MT_CHARGEAURA, + MT_SERVANTHAND, MT_HORNCODE, diff --git a/src/k_kart.c b/src/k_kart.c index 904ed2b56..da2dbb070 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -8532,8 +8532,23 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->dotrickfx && !player->mo->hitlag) { + int i; S_StartSound(player->mo, sfx_trick1); + + if (!player->trickcharge) + { + for(i = 0;i < 5;i++) + { + mobj_t *aura = P_SpawnMobjFromMobj(player->mo, 0, 0, player->mo->height/2, MT_CHARGEAURA); + aura->angle = player->mo->angle + i*ANG15; + aura->target = player->mo; + if (i != 0) + aura->renderflags |= RF_TRANS50; + } + } + player->trickcharge = 8*TICRATE; + player->dotrickfx = false; } diff --git a/src/k_objects.h b/src/k_objects.h index c88bf3320..baae5e050 100644 --- a/src/k_objects.h +++ b/src/k_objects.h @@ -126,6 +126,8 @@ void Obj_BlockRingThink(mobj_t *ring); void Obj_BlockBodyThink(mobj_t *body); void Obj_GuardBreakThink(mobj_t *fx); +void Obj_ChargeAuraThink(mobj_t *aura); + /* Ring Shooter */ boolean Obj_RingShooterThinker(mobj_t *mo); boolean Obj_PlayerRingShooterFreeze(player_t *const player); diff --git a/src/objects/CMakeLists.txt b/src/objects/CMakeLists.txt index 1e035d52d..8abbd34ee 100644 --- a/src/objects/CMakeLists.txt +++ b/src/objects/CMakeLists.txt @@ -39,6 +39,7 @@ target_sources(SRB2SDL2 PRIVATE wpzothers.c shadow.cpp ball-switch.cpp + charge.c ) add_subdirectory(versus) diff --git a/src/objects/charge.c b/src/objects/charge.c new file mode 100644 index 000000000..6566b69c3 --- /dev/null +++ b/src/objects/charge.c @@ -0,0 +1,34 @@ +#include "../doomdef.h" +#include "../info.h" +#include "../k_objects.h" +#include "../p_local.h" +#include "../k_kart.h" +#include "../k_powerup.h" + +void Obj_ChargeAuraThink (mobj_t *aura) +{ + if (P_MobjWasRemoved(aura->target) || !aura->target->player || !aura->target->player->trickcharge) + { + P_RemoveMobj(aura); + } + else + { + mobj_t *mo = aura->target; + player_t *player = mo->player; + + // Follow player + aura->flags &= ~(MF_NOCLIPTHING); + P_MoveOrigin(aura, mo->x, mo->y, mo->z + mo->height/2); + aura->flags |= MF_NOCLIPTHING; + aura->color = mo->color; + + fixed_t baseScale = 12*mo->scale/10; + P_SetScale(aura, baseScale); + + // Twirl + aura->angle = aura->angle - ANG1*(player->trickcharge/TICRATE + 4); + // Visuals + aura->renderflags |= RF_PAPERSPRITE|RF_ADD; + + } +} \ No newline at end of file diff --git a/src/p_mobj.c b/src/p_mobj.c index 565647cb7..732231631 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8781,6 +8781,11 @@ static boolean P_MobjRegularThink(mobj_t *mobj) Obj_BlockBodyThink(mobj); break; } + case MT_CHARGEAURA: + { + Obj_ChargeAuraThink(mobj); + break; + } case MT_GUARDBREAK: { Obj_GuardBreakThink(mobj); From 1adfc7f2a4272f9748fe39ce12d3864b3455d429 Mon Sep 17 00:00:00 2001 From: toaster Date: Sun, 12 Nov 2023 17:29:54 +0000 Subject: [PATCH 29/37] 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 From 3ab5da8a3ecd339f74f02a2ff31cdea7c6478bfa Mon Sep 17 00:00:00 2001 From: toaster Date: Sun, 12 Nov 2023 17:37:14 +0000 Subject: [PATCH 30/37] MT_CHARGEAURA: Fix target setting to track reference --- src/k_kart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/k_kart.c b/src/k_kart.c index 8162c1520..c9e7f1657 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -8544,7 +8544,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) { mobj_t *aura = P_SpawnMobjFromMobj(player->mo, 0, 0, player->mo->height/2, MT_CHARGEAURA); aura->angle = player->mo->angle + i*ANG15; - aura->target = player->mo; + P_SetTarget(&aura->target, player->mo); if (i != 0) aura->renderflags |= RF_TRANS50; } From 2082a372dfe054a18df9bc9d94b4892fe33dffb5 Mon Sep 17 00:00:00 2001 From: toaster Date: Sun, 12 Nov 2023 17:43:48 +0000 Subject: [PATCH 31/37] MT_FORWARDTRICK: Don't interp when your sweep returns you to the front of the player --- src/p_mobj.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/p_mobj.c b/src/p_mobj.c index a37758add..a3ce910e4 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8570,7 +8570,10 @@ static boolean P_MobjRegularThink(mobj_t *mobj) mobj->threshold += FRACUNIT/(7*4); if (mobj->threshold > FRACUNIT) + { mobj->threshold -= FRACUNIT; + mobj->flags2 |= MF2_AMBUSH; + } P_InstaScale(mobj, mobj->target->scale); From 9bb1f56fa6042d10805e3d0c447ed11bda72dd1a Mon Sep 17 00:00:00 2001 From: toaster Date: Sun, 12 Nov 2023 22:28:51 +0000 Subject: [PATCH 32/37] MT_FORWARDTRICK: Adjustments based on feedback - Animate 4x as fast without flickering - Fix interp issues - Spawn additive trail of the final frame --- src/info.c | 2 +- src/p_mobj.c | 41 ++++++++++++++++++++--------------------- 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/src/info.c b/src/info.c index 51cfc2b63..83b6407c0 100644 --- a/src/info.c +++ b/src/info.c @@ -4684,7 +4684,7 @@ state_t states[NUMSTATES] = {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_TRK7, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_ANIMATE, -1, {NULL}, 6, 1, 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 diff --git a/src/p_mobj.c b/src/p_mobj.c index a3ce910e4..c2b98d99e 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8551,32 +8551,17 @@ static boolean P_MobjRegularThink(mobj_t *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->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 + P_InstaScale(mobj, (6*mobj->target->scale)/5); + const fixed_t sweep = FixedMul(FRACUNIT - (mobj->threshold * 2), mobj->radius); - mobj->threshold += FRACUNIT/(7*4); - if (mobj->threshold > FRACUNIT) - { - mobj->threshold -= FRACUNIT; - mobj->flags2 |= MF2_AMBUSH; - } - - P_InstaScale(mobj, mobj->target->scale); - destx = mobj->target->x; desty = mobj->target->y; @@ -8588,9 +8573,9 @@ static boolean P_MobjRegularThink(mobj_t *mobj) desty += P_ReturnThrustY(mobj, mobj->movedir + ANGLE_90, sideways); if (mobj->eflags & MFE_VERTICALFLIP) - zoff += mobj->target->height - (mobj->height + 18*mobj->scale); + zoff += mobj->target->height - (mobj->height + 18*mobj->target->scale); else - zoff += 18*mobj->scale; + zoff += 18*mobj->target->scale; // Necessary to "ride" on Garden Top zoff += mobj->target->sprzoff; @@ -8604,6 +8589,20 @@ static boolean P_MobjRegularThink(mobj_t *mobj) { P_MoveOrigin(mobj, destx, desty, mobj->target->z + zoff); } + + mobj->threshold += FRACUNIT/6; + if (mobj->threshold > FRACUNIT) + { + mobj_t *puff = P_SpawnGhostMobj(mobj); + if (puff) + { + puff->renderflags = (puff->renderflags & ~RF_TRANSMASK)|RF_ADD; + } + + mobj->threshold -= FRACUNIT; + mobj->flags2 |= MF2_AMBUSH; + } + break; } case MT_LIGHTNINGSHIELD: From 041d7660ae401b5ab54398af9eae78d7e5a1403d Mon Sep 17 00:00:00 2001 From: AJ Martinez Date: Sun, 12 Nov 2023 23:32:59 -0700 Subject: [PATCH 33/37] Charge minimum viable visuals (plus future frame/obj setup) --- src/deh_tables.c | 10 +++ src/info.c | 144 +++++++++++++++++++++++++++++++++++++++++++ src/info.h | 14 +++++ src/k_kart.c | 22 ++++--- src/k_objects.h | 5 ++ src/objects/charge.c | 106 ++++++++++++++++++++++++++++++- src/p_mobj.c | 25 ++++++++ 7 files changed, 315 insertions(+), 11 deletions(-) diff --git a/src/deh_tables.c b/src/deh_tables.c index f951e365a..e80bcb37a 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -3326,6 +3326,11 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_BLOCKBODY", "S_CHARGEAURA", + "S_CHARGEFALL", + "S_CHARGEFLICKER", + "S_CHARGESPARK", + "S_CHARGERELEASE", + "S_CHARGEEXTRA", "S_SERVANTHAND", @@ -5559,6 +5564,11 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_BLOCKBODY", "MT_CHARGEAURA", + "MT_CHARGEFALL", + "MT_CHARGEFLICKER", + "MT_CHARGESPARK", + "MT_CHARGERELEASE", + "MT_CHARGEEXTRA", "MT_SERVANTHAND", diff --git a/src/info.c b/src/info.c index 83b6407c0..67f1001df 100644 --- a/src/info.c +++ b/src/info.c @@ -568,6 +568,10 @@ char sprnames[NUMSPRITES + 1][5] = "GBDY", // Guard body "TRC1", // Charge aura + "TRC2", // Charge fall + "TRC3", // Charge flicker/sparks + "TRC4", // Charge release + "TRC5", // Charge extra "DHND", // Servant Hand @@ -4142,6 +4146,11 @@ state_t states[NUMSTATES] = {SPR_GBDY, FF_FULLBRIGHT|FF_ANIMATE|0, -1, {NULL}, 4, 2, S_NULL}, // S_BLOCKBODY {SPR_TRC1, FF_FULLBRIGHT|FF_ANIMATE|0, -1, {NULL}, 4, 2, S_NULL}, // S_CHARGEAURA + {SPR_TRC2, FF_FULLBRIGHT|FF_ANIMATE|0, 20, {NULL}, 19, 1, S_NULL}, // S_CHARGEFALL + {SPR_TRC3, FF_FULLBRIGHT|FF_ADD|0, 2, {NULL}, 0, 0, S_NULL}, // S_CHARGEFLICKER + {SPR_TRC3, FF_FULLBRIGHT|FF_ADD|1, 2, {NULL}, 0, 0, S_NULL}, // S_CHARGESPARK + {SPR_TRC4, FF_FULLBRIGHT|FF_ADD|FF_ANIMATE|0, -1, {NULL}, 4, 1, S_NULL}, // S_CHARGERELEASE + {SPR_TRC5, FF_FULLBRIGHT|FF_ADD|FF_ANIMATE|0, -1, {NULL}, 4, 1, S_NULL}, // S_CHARGEEXTRA {SPR_DHND, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SERVANTHAND @@ -23274,6 +23283,141 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_CHARGEFALL + -1, // doomednum + S_CHARGEFALL, // 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 + 67*FRACUNIT, // radius + 67*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + + { // MT_CHARGEFLICKER + -1, // doomednum + S_CHARGEFLICKER, // 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 + 67*FRACUNIT, // radius + 67*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + + { // MT_CHARGESPARK + -1, // doomednum + S_CHARGESPARK, // 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 + 67*FRACUNIT, // radius + 67*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + + { // MT_CHARGERELEASE + -1, // doomednum + S_CHARGERELEASE, // 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 + 67*FRACUNIT, // radius + 67*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + + { // MT_CHARGEEXTRA + -1, // doomednum + S_CHARGEEXTRA, // 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 + 67*FRACUNIT, // radius + 67*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + { // MT_SERVANTHAND -1, // doomednum S_SERVANTHAND, // spawnstate diff --git a/src/info.h b/src/info.h index 1bb5cfdac..3d83aebed 100644 --- a/src/info.h +++ b/src/info.h @@ -1125,6 +1125,10 @@ typedef enum sprite SPR_GBDY, // Guard body SPR_TRC1, // Charge aura + SPR_TRC2, // Charge fall + SPR_TRC3, // Charge flicker/sparks + SPR_TRC4, // Charge release + SPR_TRC5, // Charge extra SPR_DHND, // Servant Hand @@ -4553,6 +4557,11 @@ typedef enum state S_BLOCKBODY, S_CHARGEAURA, + S_CHARGEFALL, + S_CHARGEFLICKER, + S_CHARGESPARK, + S_CHARGERELEASE, + S_CHARGEEXTRA, S_SERVANTHAND, @@ -6824,6 +6833,11 @@ typedef enum mobj_type MT_BLOCKBODY, MT_CHARGEAURA, + MT_CHARGEFALL, + MT_CHARGEFLICKER, + MT_CHARGESPARK, + MT_CHARGERELEASE, + MT_CHARGEEXTRA, MT_SERVANTHAND, diff --git a/src/k_kart.c b/src/k_kart.c index c9e7f1657..6f970d03a 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -8545,7 +8545,9 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) mobj_t *aura = P_SpawnMobjFromMobj(player->mo, 0, 0, player->mo->height/2, MT_CHARGEAURA); aura->angle = player->mo->angle + i*ANG15; P_SetTarget(&aura->target, player->mo); - if (i != 0) + if (i == 0) + aura->extravalue2 = 1; + else aura->renderflags |= RF_TRANS50; } } @@ -8871,14 +8873,6 @@ void K_KartResetPlayerColor(player_t *player) } } - if (player->trickcharge && (leveltime & 1)) - { - player->mo->colorized = true; - player->mo->color = SKINCOLOR_INVINCFLASH; - fullbright = true; - goto finalise; - } - if (player->ringboost && (leveltime & 1)) // ring boosting { player->mo->colorized = true; @@ -12483,9 +12477,17 @@ void K_MoveKartPlayer(player_t *player, boolean onground) { P_InstaThrust(player->mo, player->mo->angle, 2*abs(player->fastfall)/3 + 15*FRACUNIT); player->mo->hitlag = 3; - S_StartSound(player->mo, sfx_gshac); // TODO + S_StartSound(player->mo, sfx_gshba); // TODO player->fastfall = 0; // intentionally skip bounce player->trickcharge = 0; + + UINT8 i; + for (i = 0; i < 4; i++) + { + mobj_t *arc = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_CHARGEFALL); + P_SetTarget(&arc->target, player->mo); + arc->extravalue1 = i; + } } else { diff --git a/src/k_objects.h b/src/k_objects.h index baae5e050..1dc774f4f 100644 --- a/src/k_objects.h +++ b/src/k_objects.h @@ -127,6 +127,11 @@ void Obj_BlockBodyThink(mobj_t *body); void Obj_GuardBreakThink(mobj_t *fx); void Obj_ChargeAuraThink(mobj_t *aura); +void Obj_ChargeFallThink(mobj_t *charge); +void Obj_ChargeFlickerThink(mobj_t *flicker); +void Obj_ChargeSparkThink(mobj_t *spawk); +void Obj_ChargeReleaseThink(mobj_t *release); +void Obj_ChargeExtraThink(mobj_t *extra); /* Ring Shooter */ boolean Obj_RingShooterThinker(mobj_t *mo); diff --git a/src/objects/charge.c b/src/objects/charge.c index 6566b69c3..bb695ce5a 100644 --- a/src/objects/charge.c +++ b/src/objects/charge.c @@ -4,10 +4,16 @@ #include "../p_local.h" #include "../k_kart.h" #include "../k_powerup.h" +#include "../m_random.h" +#define CHARGEAURA_BURSTTIME (9) +#define CHARGEAURA_SPARKRADIUS (160) + +// xval1: destruction timer +// xval2: master (spawns other visuals) void Obj_ChargeAuraThink (mobj_t *aura) { - if (P_MobjWasRemoved(aura->target) || !aura->target->player || !aura->target->player->trickcharge) + if (P_MobjWasRemoved(aura->target) || !aura->target->player || (aura->extravalue1 >= CHARGEAURA_BURSTTIME)) { P_RemoveMobj(aura); } @@ -22,7 +28,20 @@ void Obj_ChargeAuraThink (mobj_t *aura) aura->flags |= MF_NOCLIPTHING; aura->color = mo->color; + aura->renderflags &= ~RF_DONTDRAW; + fixed_t baseScale = 12*mo->scale/10; + + if (aura->extravalue1 || !player->trickcharge) + { + aura->extravalue1++; + baseScale += (mo->scale / 3) * aura->extravalue1; + aura->renderflags &= ~RF_TRANSMASK; + aura->renderflags |= (aura->extravalue1)<extravalue1 % 2) + aura->renderflags |= RF_DONTDRAW; + } + P_SetScale(aura, baseScale); // Twirl @@ -30,5 +49,90 @@ void Obj_ChargeAuraThink (mobj_t *aura) // Visuals aura->renderflags |= RF_PAPERSPRITE|RF_ADD; + // fuck + boolean forceinvisible = !!!(leveltime % 8); + if (aura->extravalue1 || !(player->driftcharge > K_GetKartDriftSparkValueForStage(player, 3))) + forceinvisible = false; + + if (forceinvisible) + aura->renderflags |= RF_DONTDRAW; + + if (aura->extravalue2) + { + if (player->driftcharge) + { + mobj_t *spark = P_SpawnMobjFromMobj(aura, + mo->scale*P_RandomRange(PR_DECORATION, -1*CHARGEAURA_SPARKRADIUS, CHARGEAURA_SPARKRADIUS), + mo->scale*P_RandomRange(PR_DECORATION, -1*CHARGEAURA_SPARKRADIUS, CHARGEAURA_SPARKRADIUS), + mo->scale*P_RandomRange(PR_DECORATION, -1*CHARGEAURA_SPARKRADIUS, CHARGEAURA_SPARKRADIUS), + MT_CHARGESPARK); + spark->frame = P_RandomRange(PR_DECORATION, 1, 5); + P_SetTarget(&spark->target, aura); + P_SetScale(spark, 15*aura->scale/10); + } + + if (forceinvisible) + { + mobj_t *flicker = P_SpawnMobjFromMobj(aura, 0, 0, 0, MT_CHARGEFLICKER); + P_SetTarget(&flicker->target, aura); + P_SetScale(flicker, aura->scale); + } + } } +} + +void Obj_ChargeFallThink (mobj_t *charge) +{ + if (P_MobjWasRemoved(charge->target) || !charge->target->player) + { + P_RemoveMobj(charge); + } + else + { + mobj_t *mo = charge->target; + player_t *player = mo->player; + + // Follow player + charge->flags &= ~(MF_NOCLIPTHING); + P_MoveOrigin(charge, mo->x, mo->y, mo->z); + charge->flags |= MF_NOCLIPTHING; + charge->color = mo->color; + charge->angle = mo->angle + ANGLE_45 + (ANGLE_90 * charge->extravalue1); + + if (!P_IsObjectOnGround(mo)) + charge->renderflags |= RF_DONTDRAW; + else + charge->renderflags &= ~RF_DONTDRAW; + + fixed_t baseScale = 12*mo->scale/10; + P_SetScale(charge, baseScale); + + charge->renderflags &= ~RF_TRANSMASK; + if (charge->tics < 10) + charge->renderflags |= (9 - charge->tics)<renderflags |= RF_PAPERSPRITE|RF_ADD; + } +} + +void Obj_ChargeFlickerThink (mobj_t *flicker) +{ + // xd +} + +void Obj_ChargeSparkThink (mobj_t *spark) +{ + // xd + spark->renderflags |= RF_FULLBRIGHT|RF_ADD; +} + +void Obj_ChargeReleaseThink (mobj_t *flicker) +{ + // xd +} + +void Obj_ChargeExtraThink (mobj_t *flicker) +{ + // xd } \ No newline at end of file diff --git a/src/p_mobj.c b/src/p_mobj.c index c2b98d99e..4305f6cb7 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8856,6 +8856,31 @@ static boolean P_MobjRegularThink(mobj_t *mobj) Obj_ChargeAuraThink(mobj); break; } + case MT_CHARGEFALL: + { + Obj_ChargeFallThink(mobj); + break; + } + case MT_CHARGEFLICKER: + { + Obj_ChargeFlickerThink(mobj); + break; + } + case MT_CHARGESPARK: + { + Obj_ChargeSparkThink(mobj); + break; + } + case MT_CHARGERELEASE: + { + Obj_ChargeReleaseThink(mobj); + break; + } + case MT_CHARGEEXTRA: + { + Obj_ChargeExtraThink(mobj); + break; + } case MT_GUARDBREAK: { Obj_GuardBreakThink(mobj); From b946a66574fa0abdd60a315a396e7a41a36c2aec Mon Sep 17 00:00:00 2001 From: AJ Martinez Date: Mon, 13 Nov 2023 04:35:15 -0700 Subject: [PATCH 34/37] Trick Panel charge release WIP --- src/k_kart.c | 20 +++++++++++++++++++- src/objects/charge.c | 14 ++++++++++---- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 6f970d03a..c50ffd6cd 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -5218,6 +5218,18 @@ void K_SpawnDriftElectricSparks(player_t *player, int color, boolean shockwave) fixed_t sparkspeed = mobjinfo[MT_DRIFTELECTRICSPARK].speed; fixed_t sparkradius = 2 * shockscale * mobjinfo[MT_DRIFTELECTRICSPARK].radius; + if (player->trickcharge) + { + mobj_t *release = P_SpawnMobjFromMobj(mo, 0, 0, 0, MT_CHARGERELEASE); + release->momx = mo->momx/2; + release->momy = mo->momy/2; + release->momz = mo->momz/2; + release->angle = K_MomentumAngleReal(mo); + release->scale /= 5; + release->scalespeed = release->scale; + release->tics = 10; + } + for (hdir = -1; hdir <= 1; hdir += 2) { for (vdir = -1; vdir <= 1; vdir += 2) @@ -5225,12 +5237,16 @@ void K_SpawnDriftElectricSparks(player_t *player, int color, boolean shockwave) fixed_t hspeed = FixedMul(hdir * sparkspeed, mo->scale); // P_InstaThrust treats speed as absolute fixed_t vspeed = vdir * sparkspeed; // P_SetObjectMomZ scales speed with object scale angle_t sparkangle = mo->angle + ANGLE_45; + mobj_t *spark; for (i = 0; i < 4; i++) { fixed_t xoff = P_ReturnThrustX(mo, sparkangle, sparkradius); fixed_t yoff = P_ReturnThrustY(mo, sparkangle, sparkradius); - mobj_t *spark = P_SpawnMobjFromMobj(mo, x + xoff, y + yoff, z, MT_DRIFTELECTRICSPARK); + if (player->trickcharge && !shockwave) + spark = P_SpawnMobjFromMobj(mo, x + xoff, y + yoff, z, MT_CHARGEEXTRA); + else + spark = P_SpawnMobjFromMobj(mo, x + xoff, y + yoff, z, MT_DRIFTELECTRICSPARK); spark->angle = sparkangle; spark->color = color; @@ -5244,6 +5260,8 @@ void K_SpawnDriftElectricSparks(player_t *player, int color, boolean shockwave) if (shockwave) spark->frame |= FF_ADD; + else if (player->trickcharge) + spark->tics = 10; sparkangle += ANGLE_90; K_ReduceVFX(spark, player); diff --git a/src/objects/charge.c b/src/objects/charge.c index bb695ce5a..0ca6acda4 100644 --- a/src/objects/charge.c +++ b/src/objects/charge.c @@ -127,12 +127,18 @@ void Obj_ChargeSparkThink (mobj_t *spark) spark->renderflags |= RF_FULLBRIGHT|RF_ADD; } -void Obj_ChargeReleaseThink (mobj_t *flicker) +void Obj_ChargeReleaseThink (mobj_t *release) { - // xd + release->renderflags &= ~RF_TRANSMASK; + if (release->tics < 10) + release->renderflags |= (9 - release->tics)<rollangle += ANG30; } -void Obj_ChargeExtraThink (mobj_t *flicker) +void Obj_ChargeExtraThink (mobj_t *extra) { - // xd + extra->renderflags &= ~RF_TRANSMASK; + if (extra->tics < 10) + extra->renderflags |= (9 - extra->tics)<rollangle += ANG30; } \ No newline at end of file From aad6795ba7cae8186cfa9bfabfc915451b8a5f65 Mon Sep 17 00:00:00 2001 From: AJ Martinez Date: Mon, 13 Nov 2023 16:41:09 -0700 Subject: [PATCH 35/37] Trickpanels: I don't even know who I am anymore --- src/d_player.h | 1 + src/info.c | 4 ++-- src/k_kart.c | 46 ++++++++++++++++++++++++++------------------ src/k_objects.h | 2 -- src/lua_playerlib.c | 4 ++++ src/objects/charge.c | 39 ++++++++++++++++++++----------------- src/p_mobj.c | 10 ---------- src/p_saveg.c | 2 ++ src/p_user.c | 1 + 9 files changed, 58 insertions(+), 51 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 8a0b1d9b0..a49ccb8ad 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -648,6 +648,7 @@ struct player_t respawnvars_t respawn; // Respawn info mobj_t *ringShooter; // DEZ respawner object tic_t airtime; // Used to track just air time, but has evolved over time into a general "karted" timer. Rename this variable? + tic_t lastairtime; UINT8 startboost; // (0 to 125) - Boost you get from start of race UINT8 dropdashboost; // Boost you get when holding A while respawning diff --git a/src/info.c b/src/info.c index 67f1001df..e777c2784 100644 --- a/src/info.c +++ b/src/info.c @@ -23333,7 +23333,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 100, // mass 0, // damage sfx_None, // activesound - MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_SCENERY, // flags S_NULL // raisestate }, @@ -23360,7 +23360,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 100, // mass 0, // damage sfx_None, // activesound - MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_SCENERY, // flags S_NULL // raisestate }, diff --git a/src/k_kart.c b/src/k_kart.c index c50ffd6cd..a4a2db32e 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -3243,11 +3243,6 @@ static void K_GetKartBoostPower(player_t *player) ADDBOOST(8*FRACUNIT/10, 4*FRACUNIT, 2*SLIPTIDEHANDLING/5); // + 80% top speed, + 400% acceleration, +20% handling } - if (player->trickcharge) - { - ADDBOOST(0, FRACUNIT, 2*SLIPTIDEHANDLING/10); // 0% speed 100% accel 20% handle - } - if (player->spindashboost) // Spindash boost { const fixed_t MAXCHARGESPEED = K_GetSpindashChargeSpeed(player); @@ -3313,6 +3308,13 @@ static void K_GetKartBoostPower(player_t *player) ADDBOOST(6*FRACUNIT/20, FRACUNIT, 0); // + 30% top speed, + 100% acceleration, +0% handling } + if (player->trickcharge) + { + // NB: This is an acceleration-only boost. + // If this is applied earlier in the chain, it will diminish real speed boosts. + ADDBOOST(0, FRACUNIT, 2*SLIPTIDEHANDLING/10); // 0% speed 100% accel 20% handle + } + if (player->draftpower > 0) // Drafting { // 30% - 44%, each point of speed adds 1.75% @@ -5218,16 +5220,14 @@ void K_SpawnDriftElectricSparks(player_t *player, int color, boolean shockwave) fixed_t sparkspeed = mobjinfo[MT_DRIFTELECTRICSPARK].speed; fixed_t sparkradius = 2 * shockscale * mobjinfo[MT_DRIFTELECTRICSPARK].radius; - if (player->trickcharge) + if (player->trickcharge && !shockwave) { mobj_t *release = P_SpawnMobjFromMobj(mo, 0, 0, 0, MT_CHARGERELEASE); - release->momx = mo->momx/2; - release->momy = mo->momy/2; - release->momz = mo->momz/2; - release->angle = K_MomentumAngleReal(mo); + P_SetTarget(&release->target, mo); + release->tics = 40; release->scale /= 5; - release->scalespeed = release->scale; - release->tics = 10; + release->destscale *= 2; + release->scalespeed = release->scale/2; } for (hdir = -1; hdir <= 1; hdir += 2) @@ -5259,9 +5259,14 @@ void K_SpawnDriftElectricSparks(player_t *player, int color, boolean shockwave) P_SetScale(spark, shockscale * spark->scale); if (shockwave) + { spark->frame |= FF_ADD; + } else if (player->trickcharge) - spark->tics = 10; + { + spark->tics = 20; + } + sparkangle += ANGLE_90; K_ReduceVFX(spark, player); @@ -8554,7 +8559,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->dotrickfx && !player->mo->hitlag) { int i; - S_StartSound(player->mo, sfx_trick1); + S_StartSoundAtVolume(player->mo, sfx_trick1, 255/2); if (!player->trickcharge) { @@ -8567,6 +8572,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) aura->extravalue2 = 1; else aura->renderflags |= RF_TRANS50; + aura->cvmem = leveltime; } } @@ -10003,6 +10009,7 @@ static void K_KartDrift(player_t *player, boolean onground) // And take away wavedash properties: advanced cornering demands advanced finesse player->wavedash = 0; player->wavedashboost = 0; + player->trickcharge = 0; } else if ((player->pflags & PF_DRIFTINPUT) && player->drift != 0) { @@ -12306,7 +12313,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) #define TRICKTHRESHOLD (KART_FULLTURN/4) if (aimingcompare < -TRICKTHRESHOLD) // side trick { - S_StartSound(player->mo, sfx_trick0); + S_StartSoundAtVolume(player->mo, sfx_trick0, 255/2); player->dotrickfx = true; // Calculate speed boost decay: @@ -12345,7 +12352,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) } else if (aimingcompare > TRICKTHRESHOLD) // forward/back trick { - S_StartSound(player->mo, sfx_trick0); + S_StartSoundAtVolume(player->mo, sfx_trick0, 255/2); player->dotrickfx = true; // Calculate speed boost decay: @@ -12495,7 +12502,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) { P_InstaThrust(player->mo, player->mo->angle, 2*abs(player->fastfall)/3 + 15*FRACUNIT); player->mo->hitlag = 3; - S_StartSound(player->mo, sfx_gshba); // TODO + S_StartSound(player->mo, sfx_gshba); player->fastfall = 0; // intentionally skip bounce player->trickcharge = 0; @@ -12510,12 +12517,13 @@ void K_MoveKartPlayer(player_t *player, boolean onground) else { S_StartSound(player->mo, sfx_s23c); - K_SpawnDashDustRelease(player); UINT8 award = TICRATE - player->trickboostdecay; player->trickboost = award; - K_AwardPlayerRings(player, award, true); + K_AwardPlayerRings(player, + (TICRATE-player->trickboostdecay) * player->lastairtime/3 / TICRATE, // Scale ring award by same amount as trickboost + true); if (player->trickpanel == TRICKSTATE_FORWARD) player->trickboostpower /= 18; diff --git a/src/k_objects.h b/src/k_objects.h index 1dc774f4f..4a1dec35c 100644 --- a/src/k_objects.h +++ b/src/k_objects.h @@ -128,8 +128,6 @@ void Obj_GuardBreakThink(mobj_t *fx); void Obj_ChargeAuraThink(mobj_t *aura); void Obj_ChargeFallThink(mobj_t *charge); -void Obj_ChargeFlickerThink(mobj_t *flicker); -void Obj_ChargeSparkThink(mobj_t *spawk); void Obj_ChargeReleaseThink(mobj_t *release); void Obj_ChargeExtraThink(mobj_t *extra); diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index e8e928d63..ec5aeaad4 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -233,6 +233,8 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->lastpickuptype); else if (fastcmp(field,"airtime")) lua_pushinteger(L, plr->airtime); + else if (fastcmp(field,"lastairtime")) + lua_pushinteger(L, plr->lastairtime); else if (fastcmp(field,"flashing")) lua_pushinteger(L, plr->flashing); else if (fastcmp(field,"spinouttimer")) @@ -725,6 +727,8 @@ static int player_set(lua_State *L) plr->airtime = luaL_checkinteger(L, 3); else if (fastcmp(field,"airtime")) plr->airtime = luaL_checkinteger(L, 3); + else if (fastcmp(field,"lastairtime")) + plr->lastairtime = luaL_checkinteger(L, 3); else if (fastcmp(field,"flashing")) plr->flashing = luaL_checkinteger(L, 3); else if (fastcmp(field,"spinouttimer")) diff --git a/src/objects/charge.c b/src/objects/charge.c index 0ca6acda4..b4124343a 100644 --- a/src/objects/charge.c +++ b/src/objects/charge.c @@ -11,6 +11,7 @@ // xval1: destruction timer // xval2: master (spawns other visuals) +// cvmem: spawn time (used to offset flash) void Obj_ChargeAuraThink (mobj_t *aura) { if (P_MobjWasRemoved(aura->target) || !aura->target->player || (aura->extravalue1 >= CHARGEAURA_BURSTTIME)) @@ -50,7 +51,7 @@ void Obj_ChargeAuraThink (mobj_t *aura) aura->renderflags |= RF_PAPERSPRITE|RF_ADD; // fuck - boolean forceinvisible = !!!(leveltime % 8); + boolean forceinvisible = !!!((leveltime - aura->cvmem) % 4); if (aura->extravalue1 || !(player->driftcharge > K_GetKartDriftSparkValueForStage(player, 3))) forceinvisible = false; @@ -67,6 +68,7 @@ void Obj_ChargeAuraThink (mobj_t *aura) mo->scale*P_RandomRange(PR_DECORATION, -1*CHARGEAURA_SPARKRADIUS, CHARGEAURA_SPARKRADIUS), MT_CHARGESPARK); spark->frame = P_RandomRange(PR_DECORATION, 1, 5); + spark->renderflags |= RF_FULLBRIGHT|RF_ADD; P_SetTarget(&spark->target, aura); P_SetScale(spark, 15*aura->scale/10); } @@ -90,7 +92,6 @@ void Obj_ChargeFallThink (mobj_t *charge) else { mobj_t *mo = charge->target; - player_t *player = mo->player; // Follow player charge->flags &= ~(MF_NOCLIPTHING); @@ -116,29 +117,31 @@ void Obj_ChargeFallThink (mobj_t *charge) } } -void Obj_ChargeFlickerThink (mobj_t *flicker) -{ - // xd -} - -void Obj_ChargeSparkThink (mobj_t *spark) -{ - // xd - spark->renderflags |= RF_FULLBRIGHT|RF_ADD; -} - +// xval1: lifetime (used to offset from tracked player) void Obj_ChargeReleaseThink (mobj_t *release) { release->renderflags &= ~RF_TRANSMASK; - if (release->tics < 10) - release->renderflags |= (9 - release->tics)<rollangle += ANG30; + if (release->tics < 36) + release->renderflags |= (9 - release->tics/4)<rollangle += ANG15/2; + + if (P_MobjWasRemoved(release->target) || !release->target->player) + return; + + release->extravalue1++; + + fixed_t off = 8 * release->extravalue1 * release->target->scale; + angle_t ang = K_MomentumAngle(release->target) + ANGLE_180; + fixed_t xoff = FixedMul(off, FINECOSINE(ang >> ANGLETOFINESHIFT)); + fixed_t yoff = FixedMul(off, FINESINE(ang >> ANGLETOFINESHIFT)); + + P_MoveOrigin(release, release->target->x + xoff, release->target->y + yoff, release->target->z + release->target->height/2); } void Obj_ChargeExtraThink (mobj_t *extra) { extra->renderflags &= ~RF_TRANSMASK; - if (extra->tics < 10) - extra->renderflags |= (9 - extra->tics)<tics < 18) + extra->renderflags |= (9 - extra->tics/2)<rollangle += ANG30; } \ No newline at end of file diff --git a/src/p_mobj.c b/src/p_mobj.c index 4305f6cb7..715970404 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8861,16 +8861,6 @@ static boolean P_MobjRegularThink(mobj_t *mobj) Obj_ChargeFallThink(mobj); break; } - case MT_CHARGEFLICKER: - { - Obj_ChargeFlickerThink(mobj); - break; - } - case MT_CHARGESPARK: - { - Obj_ChargeSparkThink(mobj); - break; - } case MT_CHARGERELEASE: { Obj_ChargeReleaseThink(mobj); diff --git a/src/p_saveg.c b/src/p_saveg.c index 3ccab24d5..a733ab159 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -401,6 +401,7 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEUINT32(save->p, K_GetWaypointHeapIndex(players[i].currentwaypoint)); WRITEUINT32(save->p, K_GetWaypointHeapIndex(players[i].nextwaypoint)); WRITEUINT32(save->p, players[i].airtime); + WRITEUINT32(save->p, players[i].lastairtime); WRITEUINT8(save->p, players[i].startboost); WRITEUINT8(save->p, players[i].dropdashboost); @@ -936,6 +937,7 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].currentwaypoint = (waypoint_t *)(size_t)READUINT32(save->p); players[i].nextwaypoint = (waypoint_t *)(size_t)READUINT32(save->p); players[i].airtime = READUINT32(save->p); + players[i].lastairtime = READUINT32(save->p); players[i].startboost = READUINT8(save->p); players[i].dropdashboost = READUINT8(save->p); diff --git a/src/p_user.c b/src/p_user.c index a73a8124a..2c36e7f97 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4084,6 +4084,7 @@ void P_PlayerThink(player_t *player) if (P_IsObjectOnGround(player->mo) && !P_PlayerInPain(player)) // This isn't airtime, but it's control loss all the same. { + player->lastairtime = player->airtime; player->airtime = 0; } else From 0301847339293b6ea0e4be14ae851c4ecc4488b7 Mon Sep 17 00:00:00 2001 From: AJ Martinez Date: Wed, 15 Nov 2023 00:54:01 -0700 Subject: [PATCH 36/37] Fix double offset scale on charge sparks --- src/objects/charge.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/objects/charge.c b/src/objects/charge.c index b4124343a..7623b6ece 100644 --- a/src/objects/charge.c +++ b/src/objects/charge.c @@ -7,7 +7,7 @@ #include "../m_random.h" #define CHARGEAURA_BURSTTIME (9) -#define CHARGEAURA_SPARKRADIUS (160) +#define CHARGEAURA_SPARKRADIUS (40) // xval1: destruction timer // xval2: master (spawns other visuals) @@ -63,9 +63,9 @@ void Obj_ChargeAuraThink (mobj_t *aura) if (player->driftcharge) { mobj_t *spark = P_SpawnMobjFromMobj(aura, - mo->scale*P_RandomRange(PR_DECORATION, -1*CHARGEAURA_SPARKRADIUS, CHARGEAURA_SPARKRADIUS), - mo->scale*P_RandomRange(PR_DECORATION, -1*CHARGEAURA_SPARKRADIUS, CHARGEAURA_SPARKRADIUS), - mo->scale*P_RandomRange(PR_DECORATION, -1*CHARGEAURA_SPARKRADIUS, CHARGEAURA_SPARKRADIUS), + FRACUNIT*P_RandomRange(PR_DECORATION, -1*CHARGEAURA_SPARKRADIUS, CHARGEAURA_SPARKRADIUS), + FRACUNIT*P_RandomRange(PR_DECORATION, -1*CHARGEAURA_SPARKRADIUS, CHARGEAURA_SPARKRADIUS), + FRACUNIT*P_RandomRange(PR_DECORATION, -1*CHARGEAURA_SPARKRADIUS, CHARGEAURA_SPARKRADIUS), MT_CHARGESPARK); spark->frame = P_RandomRange(PR_DECORATION, 1, 5); spark->renderflags |= RF_FULLBRIGHT|RF_ADD; From f0ddb79156658399b38daae77b00e95bb98229b4 Mon Sep 17 00:00:00 2001 From: AJ Martinez Date: Wed, 15 Nov 2023 01:03:55 -0700 Subject: [PATCH 37/37] Allow bubblebounce from trick, but disable trick handling --- src/k_kart.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index ddfc36387..021e71158 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -12500,18 +12500,21 @@ void K_MoveKartPlayer(player_t *player, boolean onground) if (player->fastfall) { - P_InstaThrust(player->mo, player->mo->angle, 2*abs(player->fastfall)/3 + 15*FRACUNIT); - player->mo->hitlag = 3; - S_StartSound(player->mo, sfx_gshba); - player->fastfall = 0; // intentionally skip bounce - player->trickcharge = 0; - - UINT8 i; - for (i = 0; i < 4; i++) + if (player->curshield != KSHIELD_BUBBLE) // Allow bubblebounce (it's cute) but don't give standard trick rewards { - mobj_t *arc = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_CHARGEFALL); - P_SetTarget(&arc->target, player->mo); - arc->extravalue1 = i; + P_InstaThrust(player->mo, player->mo->angle, 2*abs(player->fastfall)/3 + 15*FRACUNIT); + player->mo->hitlag = 3; + S_StartSound(player->mo, sfx_gshba); + player->fastfall = 0; // intentionally skip bounce + player->trickcharge = 0; + + UINT8 i; + for (i = 0; i < 4; i++) + { + mobj_t *arc = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_CHARGEFALL); + P_SetTarget(&arc->target, player->mo); + arc->extravalue1 = i; + } } } else