From 87d8945f9721aadb84dd48cfa6616dcd6bd71883 Mon Sep 17 00:00:00 2001 From: AJ Martinez Date: Sun, 5 Mar 2023 23:57:47 -0700 Subject: [PATCH 01/14] Make sliptiding actually good (no visuals) 50% increased effect of handling boosts, 75% reduced penalty for handling boost stacking, grants a boost proportional to your sliptide length when you straighten out --- src/d_player.h | 4 ++++ src/k_kart.c | 37 +++++++++++++++++++++++++++++++++++-- src/lua_playerlib.c | 12 ++++++++++++ src/p_saveg.c | 8 ++++++++ 4 files changed, 59 insertions(+), 2 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 98dee8e9a..c2ad5050b 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -675,6 +675,10 @@ 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. + mobj_t *stumbleIndicator; #ifdef HWRENDER diff --git a/src/k_kart.c b/src/k_kart.c index 5e9982648..eb8962fbc 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1809,6 +1809,11 @@ static void K_SpawnGenericSpeedLines(player_t *player, boolean top) fast->colorized = true; fast->renderflags |= RF_ADD; } + else if (player->sliptideZipBoost) + { + fast->color = SKINCOLOR_WHITE; + fast->colorized = true; + } } void K_SpawnNormalSpeedLines(player_t *player) @@ -3046,7 +3051,7 @@ static void K_GetKartBoostPower(player_t *player) speedboost += FixedDiv(s, FRACUNIT + (metabolism * (numboosts-1))); \ accelboost += FixedDiv(a, FRACUNIT + (metabolism * (numboosts-1))); \ if (player->aizdriftstrat) \ - handleboost += FixedDiv(h, FRACUNIT + (metabolism * (numboosts-1))); \ + handleboost += FixedDiv(3*h/2, FRACUNIT + (metabolism * (numboosts-1))/4); \ else \ handleboost = max(h, handleboost); \ } @@ -3080,6 +3085,11 @@ static void K_GetKartBoostPower(player_t *player) ); } + if (player->sliptideZipBoost) + { + ADDBOOST(3*FRACUNIT/4, 4*FRACUNIT, sliptidehandling/2); + } + if (player->spindashboost) // Spindash boost { const fixed_t MAXCHARGESPEED = K_GetSpindashChargeSpeed(player); @@ -7483,7 +7493,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->gateBoost || player->sliptideZipBoost) { #if 0 if (player->invincibilitytimer) @@ -7745,6 +7755,11 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) player->startboost--; } + if (player->sliptideZipBoost > 0 && onground == true) + { + player->sliptideZipBoost--; + } + if (player->spindashboost) { player->spindashboost--; @@ -9205,6 +9220,8 @@ static void K_KartDrift(player_t *player, boolean onground) { K_SpawnAIZDust(player); + player->sliptideZip++; + if (abs(player->aizdrifttilt) < ANGLE_22h) { player->aizdrifttilt = @@ -9222,6 +9239,18 @@ static void K_KartDrift(player_t *player, boolean onground) if (!K_Sliptiding(player)) { + if (player->sliptideZip > 0) + { + player->sliptideZipDelay++; + if (player->sliptideZipDelay > TICRATE && player->drift == 0) + { + S_StartSound(player->mo, sfx_s3kb6); + player->sliptideZipBoost += player->sliptideZip; + player->sliptideZip = 0; + player->sliptideZipDelay = 0; + } + } + player->aizdrifttilt -= player->aizdrifttilt / 4; player->aizdriftturn -= player->aizdriftturn / 4; @@ -9230,6 +9259,10 @@ static void K_KartDrift(player_t *player, boolean onground) if (abs(player->aizdriftturn) < ANGLE_11hh) player->aizdriftturn = 0; } + else + { + player->sliptideZipDelay = 0; + } if (player->drift && ((buttons & BT_BRAKE) diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 211f83867..caa44ce58 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -308,6 +308,12 @@ 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->sliptideZipDelay); /* else if (fastcmp(field,"itemroulette")) lua_pushinteger(L, plr->itemroulette); @@ -688,6 +694,12 @@ 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->sliptideZipDelay = luaL_checkinteger(L, 3); /* else if (fastcmp(field,"itemroulette")) plr->itemroulette = luaL_checkinteger(L, 3); diff --git a/src/p_saveg.c b/src/p_saveg.c index fc9d7daf4..49d31a230 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -397,6 +397,10 @@ 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); + // respawnvars_t WRITEUINT8(save->p, players[i].respawn.state); WRITEUINT32(save->p, K_GetWaypointHeapIndex(players[i].respawn.wp)); @@ -767,6 +771,10 @@ 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); + // respawnvars_t players[i].respawn.state = READUINT8(save->p); players[i].respawn.wp = (waypoint_t *)(size_t)READUINT32(save->p); From d79e53a0e392b576a2d43adcfe1ef2dcaf2bdc96 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 3 Mar 2023 03:41:02 -0800 Subject: [PATCH 02/14] G_SaveGameData: check for NULL This fixes I_Error if used before M_NewDataStruct is called. --- src/g_game.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index a0d187790..9c9487339 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -4582,7 +4582,7 @@ void G_SaveGameData(void) UINT8 btemp; savebuffer_t save = {0}; - if (!gamedata->loaded) + if (gamedata == NULL || !gamedata->loaded) return; // If never loaded (-nodata), don't save if (usedCheats) From f4fbd1e65480e44f366611a3d75b76dca298fe17 Mon Sep 17 00:00:00 2001 From: AJ Martinez Date: Mon, 6 Mar 2023 05:00:59 -0700 Subject: [PATCH 03/14] Sliptide boost VFX first pass --- src/d_clisrv.c | 1 + src/d_player.h | 1 + src/deh_tables.c | 4 ++ src/info.c | 31 ++++++++++++++ src/info.h | 5 +++ src/k_kart.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++- src/k_kart.h | 1 + src/p_mobj.c | 2 + 8 files changed, 147 insertions(+), 1 deletion(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 76470b865..af2dfe0cd 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2561,6 +2561,7 @@ void CL_ClearPlayer(INT32 playernum) P_SetTarget(&players[playernum].followmobj, NULL); P_SetTarget(&players[playernum].hoverhyudoro, NULL); P_SetTarget(&players[playernum].stumbleIndicator, NULL); + P_SetTarget(&players[playernum].sliptideZipIndicator, NULL); } // Handle parties. diff --git a/src/d_player.h b/src/d_player.h index c2ad5050b..23f792c1b 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -680,6 +680,7 @@ struct player_t UINT16 sliptideZipBoost; // The actual boost granted from sliptideZip. mobj_t *stumbleIndicator; + mobj_t *sliptideZipIndicator; #ifdef HWRENDER fixed_t fovadd; // adjust FOV for hw rendering diff --git a/src/deh_tables.c b/src/deh_tables.c index de88639e8..1745d9a7d 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -3304,6 +3304,8 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_MAGICIANBOXTOP", "S_MAGICIANBOXBOTTOM", + "S_SLIPTIDEZIP", + // Signpost sparkles "S_SIGNSPARK1", "S_SIGNSPARK2", @@ -5323,6 +5325,8 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_MONITOR_PART", "MT_MONITOR_SHARD", "MT_MAGICIANBOX", + + "MT_SLIPTIDEZIP", "MT_SIGNSPARKLE", diff --git a/src/info.c b/src/info.c index d0509e731..4d799efe9 100644 --- a/src/info.c +++ b/src/info.c @@ -552,6 +552,8 @@ char sprnames[NUMSPRITES + 1][5] = "IMDB", // Item Monitor Small Shard (Debris) "MTWK", // Item Monitor Glass Twinkle + "SLPT", // Sliptide zip indicator + "WIPD", // Wipeout dust trail "DRIF", // Drift Sparks "BDRF", // Brake drift sparks @@ -3930,6 +3932,8 @@ 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_SGNS, FF_ADD|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_SIGNSPARK2}, // S_SIGNSPARK1 {SPR_SGNS, FF_ADD|FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_SIGNSPARK3}, // S_SIGNSPARK2 {SPR_SGNS, FF_ADD|FF_FULLBRIGHT|2, 1, {NULL}, 0, 0, S_SIGNSPARK4}, // S_SIGNSPARK3 @@ -22583,6 +22587,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPTHING|MF_NOCLIPHEIGHT, // flags S_NULL // raisestate }, + + { // MT_SLIPTIDEZIP + -1, // doomednum + S_SLIPTIDEZIP, // 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 + 20*FRACUNIT, // radius + 20*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_NOCLIPTHING, // flags + S_NULL // raisestate + }, { // MT_SIGNSPARKLE -1, // doomednum diff --git a/src/info.h b/src/info.h index 02e194cb6..3a1921b3c 100644 --- a/src/info.h +++ b/src/info.h @@ -1103,6 +1103,8 @@ typedef enum sprite SPR_IMDB, // Item Monitor Small Shard (Debris) SPR_MTWK, // Item Monitor Glass Twinkle + SPR_SLPT, // Sliptide zip indicator + SPR_WIPD, // Wipeout dust trail SPR_DRIF, // Drift Sparks SPR_BDRF, // Brake drift sparks @@ -4339,6 +4341,8 @@ typedef enum state S_MAGICIANBOX_TOP, S_MAGICIANBOX_BOTTOM, + S_SLIPTIDEZIP, + // Signpost sparkles S_SIGNSPARK1, S_SIGNSPARK2, @@ -6394,6 +6398,7 @@ typedef enum mobj_type MT_MONITOR_PART, MT_MONITOR_SHARD, MT_MAGICIANBOX, + MT_SLIPTIDEZIP, MT_SIGNSPARKLE, diff --git a/src/k_kart.c b/src/k_kart.c index eb8962fbc..b4b12b7e1 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -3883,6 +3883,31 @@ void K_InitStumbleIndicator(player_t *player) P_SetTarget(&new->target, player->mo); } +void K_InitSliptideZipIndicator(player_t *player) +{ + mobj_t *new = NULL; + + if (player == NULL) + { + return; + } + + if (player->mo == NULL || P_MobjWasRemoved(player->mo) == true) + { + return; + } + + if (player->stumbleIndicator != NULL && P_MobjWasRemoved(player->sliptideZipIndicator) == false) + { + P_RemoveMobj(player->sliptideZipIndicator); + } + + new = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_SLIPTIDEZIP); + + P_SetTarget(&player->sliptideZipIndicator, new); + P_SetTarget(&new->target, player->mo); +} + void K_UpdateStumbleIndicator(player_t *player) { const angle_t fudge = ANG15; @@ -3985,6 +4010,71 @@ void K_UpdateStumbleIndicator(player_t *player) } } +void K_UpdateSliptideZipIndicator(player_t *player) +{ + mobj_t *mobj = NULL; + + if (player == NULL) + { + return; + } + + if (player->mo == NULL || P_MobjWasRemoved(player->mo) == true) + { + return; + } + + if (player->stumbleIndicator == NULL || P_MobjWasRemoved(player->stumbleIndicator) == true) + { + K_InitSliptideZipIndicator(player); + return; + } + + mobj = player->sliptideZipIndicator; + angle_t momentumAngle = R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy); + + P_MoveOrigin(mobj, player->mo->x - FixedMul(40*mapobjectscale, FINECOSINE(momentumAngle >> ANGLETOFINESHIFT)), + player->mo->y - FixedMul(40*mapobjectscale, FINESINE(momentumAngle >> ANGLETOFINESHIFT)), + player->mo->z + (player->mo->height / 2)); + mobj->angle = momentumAngle + ANGLE_90; + P_SetScale(mobj, 3 * player->mo->scale / 2); + + mobj->renderflags &= ~RF_DONTDRAW; + + // No stored boost + if (player->sliptideZip == 0) + { + mobj->renderflags |= RF_DONTDRAW; + mobj->frame = 7; + return; + } + + UINT32 chargeFrame = 7 - min(7, player->sliptideZip / 10); + UINT32 decayFrame = min(7, player->sliptideZipDelay / 5); + if (max(chargeFrame, decayFrame) > mobj->frame) + mobj->frame++; + else if (max(chargeFrame, decayFrame) < mobj->frame) + mobj->frame--; + + CONS_Printf("%d/%d\n", chargeFrame, decayFrame); + + mobj->renderflags &= ~RF_TRANSMASK; + mobj->renderflags |= RF_PAPERSPRITE; + + if (!K_Sliptiding(player) && player->drift == 0) + { + // Decay timer's ticking + mobj->rollangle += 3*ANG30/4; + if (leveltime % 2 == 0) + mobj->renderflags |= RF_TRANS50; + } + else + { + // Storing boost + mobj->rollangle += 3*ANG15/4; + } +} + static boolean K_LastTumbleBounceCondition(player_t *player) { return (player->tumbleBounces > TUMBLEBOUNCES && player->tumbleHeight < 60); @@ -8129,6 +8219,8 @@ void K_KartPlayerAfterThink(player_t *player) K_UpdateStumbleIndicator(player); + K_UpdateSliptideZipIndicator(player); + // Move held objects (Bananas, Orbinaut, etc) K_MoveHeldObjects(player); @@ -9239,13 +9331,14 @@ static void K_KartDrift(player_t *player, boolean onground) if (!K_Sliptiding(player)) { - if (player->sliptideZip > 0) + if (player->sliptideZip > 0 && player->drift == 0) { player->sliptideZipDelay++; if (player->sliptideZipDelay > TICRATE && player->drift == 0) { S_StartSound(player->mo, sfx_s3kb6); player->sliptideZipBoost += player->sliptideZip; + K_SpawnDriftBoostExplosion(player, 0); player->sliptideZip = 0; player->sliptideZipDelay = 0; } @@ -9703,6 +9796,9 @@ static void K_KartSpindashWind(mobj_t *parent) P_SetTarget(&wind->target, parent); + if (parent->player && parent->player->sliptideZipBoost) + P_SetScale(wind, wind->scale * 2); + if (parent->momx || parent->momy) wind->angle = R_PointToAngle2(0, 0, parent->momx, parent->momy); else @@ -9778,6 +9874,11 @@ static void K_KartSpindash(player_t *player) K_KartSpindashWind(player->mo); } + if ((player->sliptideZipBoost > 0) && (spawnWind == true)) + { + K_KartSpindashWind(player->mo); + } + if (player->spindashboost > (TICRATE/2)) { K_KartSpindashDust(player->mo); diff --git a/src/k_kart.h b/src/k_kart.h index 04610be45..3409bb5d2 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -99,6 +99,7 @@ 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_UpdateStumbleIndicator(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/p_mobj.c b/src/p_mobj.c index 8fe24ffed..00bd35fa5 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11794,6 +11794,8 @@ void P_SpawnPlayer(INT32 playernum) K_InitStumbleIndicator(p); + K_InitSliptideZipIndicator(p); + if (gametyperules & GTR_ITEMARROWS) { mobj_t *overheadarrow = P_SpawnMobj(mobj->x, mobj->y, mobj->z + mobj->height + 16*FRACUNIT, MT_PLAYERARROW); From 2e418628023d9ce329cfbba90f7a604ef45cab0e Mon Sep 17 00:00:00 2001 From: AJ Martinez Date: Mon, 6 Mar 2023 05:03:39 -0700 Subject: [PATCH 04/14] Please fucking stage the files I tell you to stage --- src/k_kart.c | 2 -- src/k_kart.h | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index b4b12b7e1..7ecb517b8 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4056,8 +4056,6 @@ void K_UpdateSliptideZipIndicator(player_t *player) else if (max(chargeFrame, decayFrame) < mobj->frame) mobj->frame--; - CONS_Printf("%d/%d\n", chargeFrame, decayFrame); - mobj->renderflags &= ~RF_TRANSMASK; mobj->renderflags |= RF_PAPERSPRITE; diff --git a/src/k_kart.h b/src/k_kart.h index 3409bb5d2..6ab2fbfb0 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -101,6 +101,7 @@ boolean K_CheckStumble(player_t *player, angle_t oldPitch, angle_t oldRoll, bool void K_InitStumbleIndicator(player_t *player); void K_InitSliptideZipIndicator(player_t *player); void K_UpdateStumbleIndicator(player_t *player); +void K_UpdateSliptideZipIndicator(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_HandleBumperChanges(player_t *player, UINT8 prevBumpers); From c2c2c71f0a01aec9a220e4dc5756ae84a214efca Mon Sep 17 00:00:00 2001 From: AJ Martinez Date: Mon, 6 Mar 2023 05:17:26 -0700 Subject: [PATCH 05/14] Freeze sliptide zip delay while airborne --- src/k_kart.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 7ecb517b8..906b519a8 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4059,7 +4059,7 @@ void K_UpdateSliptideZipIndicator(player_t *player) mobj->renderflags &= ~RF_TRANSMASK; mobj->renderflags |= RF_PAPERSPRITE; - if (!K_Sliptiding(player) && player->drift == 0) + if (!K_Sliptiding(player) && player->drift == 0 && P_IsObjectOnGround(player->mo)) { // Decay timer's ticking mobj->rollangle += 3*ANG30/4; @@ -9329,10 +9329,10 @@ static void K_KartDrift(player_t *player, boolean onground) if (!K_Sliptiding(player)) { - if (player->sliptideZip > 0 && player->drift == 0) + if (player->sliptideZip > 0 && player->drift == 0 && P_IsObjectOnGround(player->mo)) { player->sliptideZipDelay++; - if (player->sliptideZipDelay > TICRATE && player->drift == 0) + if (player->sliptideZipDelay > TICRATE) { S_StartSound(player->mo, sfx_s3kb6); player->sliptideZipBoost += player->sliptideZip; From 8951ccf61dd7a2b9059cc98c1c7cfcfb64d7e760 Mon Sep 17 00:00:00 2001 From: AJ Martinez Date: Mon, 6 Mar 2023 05:43:02 -0700 Subject: [PATCH 06/14] Buff sliptide zip --- 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 906b519a8..a428d4936 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -3087,7 +3087,7 @@ static void K_GetKartBoostPower(player_t *player) if (player->sliptideZipBoost) { - ADDBOOST(3*FRACUNIT/4, 4*FRACUNIT, sliptidehandling/2); + ADDBOOST(FRACUNIT, 4*FRACUNIT, sliptidehandling/2); // + 100% top speed, + 400% acceleration, +25% handling } if (player->spindashboost) // Spindash boost From 5dea8f9bbabfe15445c99cf2c7cd31ad6201ccce Mon Sep 17 00:00:00 2001 From: AJ Martinez Date: Mon, 6 Mar 2023 05:43:14 -0700 Subject: [PATCH 07/14] Break zip combo when dying, idiot --- src/k_respawn.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/k_respawn.c b/src/k_respawn.c index cb08408a2..936216f8f 100644 --- a/src/k_respawn.c +++ b/src/k_respawn.c @@ -159,6 +159,7 @@ void K_DoIngameRespawn(player_t *player) player->ringboost = 0; player->driftboost = player->strongdriftboost = 0; player->gateBoost = 0; + player->sliptideZip = player->sliptideZipBoost = player->sliptideZipDelay = 0; K_TumbleInterrupt(player); P_ResetPlayer(player); From cae8cd5100070e7554fc0a179e3c2a9d8e36c98e Mon Sep 17 00:00:00 2001 From: AJ Martinez Date: Mon, 6 Mar 2023 06:07:55 -0700 Subject: [PATCH 08/14] Don't encore remap sliptide zip indicator --- src/info.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/info.c b/src/info.c index 4d799efe9..f0bbf1187 100644 --- a/src/info.c +++ b/src/info.c @@ -22611,7 +22611,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 100, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_NOCLIPTHING, // flags + MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_NOCLIPTHING|MF_DONTENCOREMAP, // flags S_NULL // raisestate }, From 08ddc324c307d8f75274b10db30a03bb8b697c3c Mon Sep 17 00:00:00 2001 From: AJ Martinez Date: Mon, 6 Mar 2023 06:11:13 -0700 Subject: [PATCH 09/14] Fix potential ADDBOOST macro footgun --- 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 a428d4936..57df9242b 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -3051,7 +3051,7 @@ static void K_GetKartBoostPower(player_t *player) speedboost += FixedDiv(s, FRACUNIT + (metabolism * (numboosts-1))); \ accelboost += FixedDiv(a, FRACUNIT + (metabolism * (numboosts-1))); \ if (player->aizdriftstrat) \ - handleboost += FixedDiv(3*h/2, FRACUNIT + (metabolism * (numboosts-1))/4); \ + handleboost += FixedDiv((3*h)/2, FRACUNIT + (metabolism * (numboosts-1))/4); \ else \ handleboost = max(h, handleboost); \ } From 948dea83043b16520e9223638f5acd6041bfabba Mon Sep 17 00:00:00 2001 From: AJ Martinez Date: Mon, 6 Mar 2023 06:17:34 -0700 Subject: [PATCH 10/14] Sliptide zip readability --- src/k_kart.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 57df9242b..931064b83 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4039,8 +4039,6 @@ void K_UpdateSliptideZipIndicator(player_t *player) mobj->angle = momentumAngle + ANGLE_90; P_SetScale(mobj, 3 * player->mo->scale / 2); - mobj->renderflags &= ~RF_DONTDRAW; - // No stored boost if (player->sliptideZip == 0) { @@ -4049,6 +4047,8 @@ void K_UpdateSliptideZipIndicator(player_t *player) return; } + mobj->renderflags &= ~RF_DONTDRAW; + UINT32 chargeFrame = 7 - min(7, player->sliptideZip / 10); UINT32 decayFrame = min(7, player->sliptideZipDelay / 5); if (max(chargeFrame, decayFrame) > mobj->frame) From 15a0eb6c48547534239fe0f384d5cee56ba01b87 Mon Sep 17 00:00:00 2001 From: AJ Martinez Date: Mon, 6 Mar 2023 06:26:21 -0700 Subject: [PATCH 11/14] Add sliptideZipIndicator to netsave --- src/p_saveg.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/p_saveg.c b/src/p_saveg.c index 49d31a230..c420646b4 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -67,6 +67,7 @@ typedef enum SKYBOXCENTER = 0x10, HOVERHYUDORO = 0x20, STUMBLE = 0x40, + SLIPTIDEZIP = 0x80 } player_saveflags; static inline void P_ArchivePlayer(savebuffer_t *save) @@ -218,6 +219,9 @@ static void P_NetArchivePlayers(savebuffer_t *save) if (players[i].stumbleIndicator) flags |= STUMBLE; + if (players[i].sliptideZipIndicator) + flags |= SLIPTIDEZIP; + WRITEUINT16(save->p, flags); if (flags & SKYBOXVIEW) @@ -238,6 +242,9 @@ 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); + WRITEUINT32(save->p, (UINT32)players[i].followitem); WRITEUINT32(save->p, players[i].charflags); @@ -611,6 +618,9 @@ 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); + players[i].followitem = (mobjtype_t)READUINT32(save->p); //SetPlayerSkinByNum(i, players[i].skin); @@ -4754,6 +4764,13 @@ 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) + { + 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); + } } } From 2fb6bc5f46918e952a2bc3cd2a857b1f11c03774 Mon Sep 17 00:00:00 2001 From: AJ Martinez Date: Mon, 6 Mar 2023 16:51:41 -0700 Subject: [PATCH 12/14] Require 25% minimum handleboost to sliptide, change sliptide zip to 24% --- src/k_kart.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 931064b83..beae28100 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -3045,12 +3045,15 @@ static void K_GetKartBoostPower(player_t *player) boostpower = (4*boostpower)/5; // Note: Handling will ONLY stack when sliptiding! + // > (NB 2023-03-06: This was previously unintentionally applied while drifting as well.) + // > (This only affected drifts where you were under the effect of multiple handling boosts.) + // > (Revisit if Growvinciblity or sneaker-panels + power items feel too heavy while drifting!) // When you're not, it just uses the best instead of adding together, like the old behavior. #define ADDBOOST(s,a,h) { \ numboosts++; \ speedboost += FixedDiv(s, FRACUNIT + (metabolism * (numboosts-1))); \ accelboost += FixedDiv(a, FRACUNIT + (metabolism * (numboosts-1))); \ - if (player->aizdriftstrat) \ + if (K_Sliptiding(player)) \ handleboost += FixedDiv((3*h)/2, FRACUNIT + (metabolism * (numboosts-1))/4); \ else \ handleboost = max(h, handleboost); \ @@ -3087,7 +3090,8 @@ static void K_GetKartBoostPower(player_t *player) if (player->sliptideZipBoost) { - ADDBOOST(FRACUNIT, 4*FRACUNIT, sliptidehandling/2); // + 100% top speed, + 400% acceleration, +25% handling + // NB: This is intentionally under the 25% threshold required to initiate a sliptide + ADDBOOST(FRACUNIT, 4*FRACUNIT, 2*sliptidehandling/5); // + 100% top speed, + 400% acceleration, +20% handling } if (player->spindashboost) // Spindash boost @@ -9296,7 +9300,7 @@ static void K_KartDrift(player_t *player, boolean onground) player->pflags &= ~PF_DRIFTEND; } - if ((player->handleboost == 0) + if ((player->handleboost < FRACUNIT/4) || (!player->steering) || (!player->aizdriftstrat) || (player->steering > 0) != (player->aizdriftstrat > 0)) From a7cc5aac788ecd1c377dd84a21fcc133d6afc7d6 Mon Sep 17 00:00:00 2001 From: AJ Martinez Date: Mon, 6 Mar 2023 16:53:14 -0700 Subject: [PATCH 13/14] Fix Lua interface mangling writes to sliptideZipBoost --- src/lua_playerlib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index caa44ce58..1edf0cdd8 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -313,7 +313,7 @@ static int player_get(lua_State *L) else if (fastcmp(field,"sliptideZipDelay")) lua_pushinteger(L, plr->sliptideZipDelay); else if (fastcmp(field,"sliptideZipBoost")) - lua_pushinteger(L, plr->sliptideZipDelay); + lua_pushinteger(L, plr->sliptideZipBoost); /* else if (fastcmp(field,"itemroulette")) lua_pushinteger(L, plr->itemroulette); @@ -699,7 +699,7 @@ static int player_set(lua_State *L) else if (fastcmp(field,"sliptideZipDelay")) plr->sliptideZipDelay = luaL_checkinteger(L, 3); else if (fastcmp(field,"sliptideZipBoost")) - plr->sliptideZipDelay = luaL_checkinteger(L, 3); + plr->sliptideZipBoost = luaL_checkinteger(L, 3); /* else if (fastcmp(field,"itemroulette")) plr->itemroulette = luaL_checkinteger(L, 3); From 5d79ecd065896e13d6d1a505c918feda8a6fbf62 Mon Sep 17 00:00:00 2001 From: AJ Martinez Date: Mon, 6 Mar 2023 20:01:09 -0700 Subject: [PATCH 14/14] Oni feedback fixup Sneaker boosts now pause decay timer, boost strength reduced to prevent tripwire memes, boost lengthened based on proximity to bottom left, further improvements to handling boosts --- src/k_kart.c | 64 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 47 insertions(+), 17 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index beae28100..def6c4be3 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -3016,6 +3016,10 @@ fixed_t K_GetSpindashChargeSpeed(player_t *player) return val; } +// v2 almost broke sliptiding when it fixed turning bugs! +// This value is fine-tuned to feel like v1 again without reverting any of those changes. +#define SLIPTIDEHANDLING 7*FRACUNIT/8 + // sets boostpower, speedboost, accelboost, and handleboost to whatever we need it to be static void K_GetKartBoostPower(player_t *player) { @@ -3023,10 +3027,6 @@ static void K_GetKartBoostPower(player_t *player) const fixed_t maxmetabolismincrease = FRACUNIT/2; const fixed_t metabolism = FRACUNIT - ((9-player->kartweight) * maxmetabolismincrease / 8); - // v2 almost broke sliptiding when it fixed turning bugs! - // This value is fine-tuned to feel like v1 again without reverting any of those changes. - const fixed_t sliptidehandling = FRACUNIT/2; - fixed_t boostpower = FRACUNIT; fixed_t speedboost = 0, accelboost = 0, handleboost = 0; UINT8 numboosts = 0; @@ -3054,7 +3054,7 @@ static void K_GetKartBoostPower(player_t *player) speedboost += FixedDiv(s, FRACUNIT + (metabolism * (numboosts-1))); \ accelboost += FixedDiv(a, FRACUNIT + (metabolism * (numboosts-1))); \ if (K_Sliptiding(player)) \ - handleboost += FixedDiv((3*h)/2, FRACUNIT + (metabolism * (numboosts-1))/4); \ + handleboost += FixedDiv(h, FRACUNIT + (metabolism * (numboosts-1))/4); \ else \ handleboost = max(h, handleboost); \ } @@ -3064,18 +3064,18 @@ static void K_GetKartBoostPower(player_t *player) UINT8 i; for (i = 0; i < player->numsneakers; i++) { - ADDBOOST(FRACUNIT/2, 8*FRACUNIT, sliptidehandling); // + 50% top speed, + 800% acceleration, +50% handling + ADDBOOST(FRACUNIT/2, 8*FRACUNIT, SLIPTIDEHANDLING); // + 50% top speed, + 800% acceleration, +50% handling } } if (player->invincibilitytimer) // Invincibility { - ADDBOOST(3*FRACUNIT/8, 3*FRACUNIT, sliptidehandling/2); // + 37.5% top speed, + 300% acceleration, +25% handling + ADDBOOST(3*FRACUNIT/8, 3*FRACUNIT, SLIPTIDEHANDLING/2); // + 37.5% top speed, + 300% acceleration, +25% handling } if (player->growshrinktimer > 0) // Grow { - ADDBOOST(0, 0, sliptidehandling/2); // + 0% top speed, + 0% acceleration, +25% handling + ADDBOOST(0, 0, SLIPTIDEHANDLING/2); // + 0% top speed, + 0% acceleration, +25% handling } if (player->flamedash) // Flame Shield dash @@ -3084,14 +3084,14 @@ static void K_GetKartBoostPower(player_t *player) ADDBOOST( dash, // + infinite top speed 3*FRACUNIT, // + 300% acceleration - FixedMul(FixedDiv(dash, FRACUNIT/2), sliptidehandling/2) // + infinite handling + FixedMul(FixedDiv(dash, FRACUNIT/2), SLIPTIDEHANDLING/2) // + infinite handling ); } if (player->sliptideZipBoost) { // NB: This is intentionally under the 25% threshold required to initiate a sliptide - ADDBOOST(FRACUNIT, 4*FRACUNIT, 2*sliptidehandling/5); // + 100% top speed, + 400% acceleration, +20% handling + ADDBOOST(13*FRACUNIT/20, 4*FRACUNIT, 2*SLIPTIDEHANDLING/5); // + 65% top speed, + 400% acceleration, +20% handling } if (player->spindashboost) // Spindash boost @@ -3109,7 +3109,7 @@ static void K_GetKartBoostPower(player_t *player) if (player->startboost) // Startup Boost { - ADDBOOST(FRACUNIT, 4*FRACUNIT, sliptidehandling); // + 100% top speed, + 400% acceleration, +50% handling + ADDBOOST(FRACUNIT, 4*FRACUNIT, SLIPTIDEHANDLING); // + 100% top speed, + 400% acceleration, +50% handling } if (player->driftboost) // Drift Boost @@ -3139,7 +3139,7 @@ static void K_GetKartBoostPower(player_t *player) if (player->gateBoost) // SPB Juicebox boost { - ADDBOOST(3*FRACUNIT/4, 4*FRACUNIT, sliptidehandling/2); // + 75% top speed, + 400% acceleration, +25% handling + ADDBOOST(3*FRACUNIT/4, 4*FRACUNIT, SLIPTIDEHANDLING/2); // + 75% top speed, + 400% acceleration, +25% handling } if (player->ringboost) // Ring Boost @@ -4014,6 +4014,15 @@ void K_UpdateStumbleIndicator(player_t *player) } } +static boolean K_IsLosingSliptideZip(player_t *player) +{ + if (player->mo == NULL || P_MobjWasRemoved(player->mo) == true) + return true; + if (!K_Sliptiding(player) && player->drift == 0 && P_IsObjectOnGround(player->mo) && player->sneakertimer == 0) + return true; + return false; +} + void K_UpdateSliptideZipIndicator(player_t *player) { mobj_t *mobj = NULL; @@ -4063,7 +4072,7 @@ void K_UpdateSliptideZipIndicator(player_t *player) mobj->renderflags &= ~RF_TRANSMASK; mobj->renderflags |= RF_PAPERSPRITE; - if (!K_Sliptiding(player) && player->drift == 0 && P_IsObjectOnGround(player->mo)) + if (K_IsLosingSliptideZip(player)) { // Decay timer's ticking mobj->rollangle += 3*ANG30/4; @@ -9300,7 +9309,7 @@ static void K_KartDrift(player_t *player, boolean onground) player->pflags &= ~PF_DRIFTEND; } - if ((player->handleboost < FRACUNIT/4) + if ((player->handleboost < (SLIPTIDEHANDLING/2)) || (!player->steering) || (!player->aizdriftstrat) || (player->steering > 0) != (player->aizdriftstrat > 0)) @@ -9333,16 +9342,37 @@ static void K_KartDrift(player_t *player, boolean onground) if (!K_Sliptiding(player)) { - if (player->sliptideZip > 0 && player->drift == 0 && P_IsObjectOnGround(player->mo)) + if (K_IsLosingSliptideZip(player) && player->sliptideZip > 0) { player->sliptideZipDelay++; if (player->sliptideZipDelay > TICRATE) { - S_StartSound(player->mo, sfx_s3kb6); - player->sliptideZipBoost += player->sliptideZip; + fixed_t maxZipPower = 2*FRACUNIT; + fixed_t minZipPower = 1*FRACUNIT; + fixed_t powerSpread = maxZipPower - minZipPower; + + int minPenalty = 2*1 + (9-9); // Kinda doing a similar thing to driftspark stage timers here. + int maxPenalty = 2*9 + (9-1); // 1/9 gets max, 9/1 gets min, everyone else gets something in between. + int penaltySpread = maxPenalty - minPenalty; + int yourPenalty = 2*player->kartspeed + (9 - player->kartweight); // And like driftsparks, speed hurts double. + + yourPenalty -= minPenalty; // Normalize; minimum penalty should take away 0 power. + + fixed_t yourPowerReduction = FixedDiv(yourPenalty * FRACUNIT, penaltySpread * FRACUNIT); + fixed_t yourPower = maxZipPower - FixedMul(yourPowerReduction, powerSpread); + int yourBoost = FixedInt(FixedMul(yourPower, player->sliptideZip * 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); + */ + + player->sliptideZipBoost += yourBoost; + K_SpawnDriftBoostExplosion(player, 0); player->sliptideZip = 0; player->sliptideZipDelay = 0; + S_StartSound(player->mo, sfx_s3kb6); } }