diff --git a/src/d_netcmd.c b/src/d_netcmd.c index a3aa6782d..57f0719a7 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -490,6 +490,8 @@ consvar_t cv_kartbumpspark = CVAR_INIT ("kartbumpspark", "No", CV_NETVAR, CV_Yes consvar_t cv_kartbumpspring = CVAR_INIT ("kartbumpspring", "No", CV_NETVAR, CV_YesNo, NULL); +consvar_t cv_kartslipdash = CVAR_INIT ("kartslipdash", "No", CV_NETVAR, CV_YesNo, NULL); + static CV_PossibleValue_t kartdebugitem_cons_t[] = { #define FOREACH( name, n ) { n, #name } diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 6ddf593c8..c1e7dd2d2 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -157,8 +157,8 @@ extern consvar_t cv_kartitembreaker; extern consvar_t cv_kartwalltransfer; extern consvar_t cv_kartpurpledrift; extern consvar_t cv_kartbumpspark; - extern consvar_t cv_kartbumpspring; +extern consvar_t cv_kartslipdash; extern consvar_t cv_votetime; diff --git a/src/d_player.h b/src/d_player.h index f17621d82..5fb29aca0 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -577,6 +577,8 @@ struct player_t SINT8 aizdriftstrat; // (-1 to 1) - Let go of your drift while boosting? Helper for the SICK STRATZ (sliptiding!) you have just unlocked INT32 aizdrifttilt; INT32 aizdriftturn; + fixed_t slipdashcharge; // charge up a dash with a sliptide! + SINT8 slipdashdir; // no snaking allowed :^) fixed_t offroad; // In Super Mario Kart, going offroad has lee-way of about 1 second before you start losing speed UINT8 pogospring; // Pogo spring bounce effect diff --git a/src/k_kart.c b/src/k_kart.c index 79237decc..6fdf354cc 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -310,6 +310,8 @@ void K_RegisterKartStuff(void) CV_RegisterVar(&cv_kartbumpspring); + CV_RegisterVar(&cv_kartslipdash); + CV_RegisterVar(&cv_kartdriftsounds); CV_RegisterVar(&cv_kartdriftefx); @@ -9075,7 +9077,7 @@ static void K_KartDrift(player_t *player, boolean onground) else player->aizdriftstrat = ((player->drift > 0) ? 1 : -1); } - else if (player->aizdriftstrat && !player->drift) + else if (K_Sliptiding(player)) { K_SpawnAIZDust(player); @@ -9118,6 +9120,79 @@ static void K_KartDrift(player_t *player, boolean onground) player->pflags &= ~PF_BRAKEDRIFT; } +static void K_KartSlipdash(player_t *player, boolean onground) +{ + boolean snaked = player->slipdashdir && player->aizdriftstrat && player->slipdashdir != player->aizdriftstrat; + if (!cv_kartslipdash.value || player->spinouttimer) + { + player->slipdashcharge = 0; + player->slipdashdir = 0; + } + else if ((K_Sliptiding(player) || player->aizdriftturn) && !snaked) + { + if (!player->slipdashdir) // anti-snaking + player->slipdashdir = player->aizdriftstrat; + + if (onground && !player->drift) + { + fixed_t turn = max(0, player->cmd.turning * player->aizdriftstrat); + turn = FINETANGENT((turn*(ANGLE_45/KART_FULLTURN) + ANGLE_90) >> ANGLETOFINESHIFT); + player->slipdashcharge = min(player->slipdashcharge + turn/50, FRACUNIT); + + if (!(leveltime % 5)) + S_StartSoundAtVolume(player->mo, sfx_cdfm17, 133 + turn/555); + } + } + else if (player->slipdashcharge && onground) + { + INT32 i; + boolean driftbonus = player->driftcharge && !snaked; + + if (snaked) + player->slipdashcharge /= 4; + + S_StopSoundByID(player->mo, sfx_cdfm17); + S_StartSoundAtVolume(player->mo, player->slipdashcharge > FRACUNIT/3 ? sfx_cdfm62 : sfx_s23c, driftbonus ? 200 : 255); + P_Thrust(player->mo, player->mo->angle, FixedMul(K_GetKartSpeed(player, false, false), 2*player->slipdashcharge/3)); + + for (i = -1; i <= 1; i += 2) + { + mobj_t *strat = P_SpawnMobjFromMobj(player->mo, + P_ReturnThrustX(NULL, player->mo->angle + ANGLE_67h*i, -20*player->mo->scale), + P_ReturnThrustY(NULL, player->mo->angle + ANGLE_67h*i, -20*player->mo->scale), + 0, MT_AIZDRIFTSTRAT + ); + strat->angle = player->mo->angle + ANGLE_67h*i; + P_SetScale(strat, FixedMul(player->slipdashcharge + FRACUNIT/4, mapobjectscale)); + strat->destscale = strat->scale; + strat->momx = P_ReturnThrustX(NULL, player->mo->angle, -8*mapobjectscale); + strat->momy = P_ReturnThrustY(NULL, player->mo->angle, -8*mapobjectscale); + } + + if (driftbonus) + { + INT32 dsv = K_GetKartDriftSparkValue(player); + player->driftcharge = min(player->driftcharge + FixedMul(player->slipdashcharge, dsv), dsv-1); + S_StartSound(player->mo, sfx_s3k45); + } + + player->slipdashcharge = 0; + player->slipdashdir = 0; + } + else + player->slipdashdir = 0; + + if (player->slipdashcharge) + { + mobj_t *spark = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_DRIFTSPARK); + spark->color = SKINCOLOR_GREEN; + spark->angle = player->mo->angle + player->aizdriftstrat*ANGLE_45; + P_SetScale(spark, FixedMul(player->slipdashcharge + 2*FRACUNIT/3, mapobjectscale)); + spark->destscale = 0; + spark->scalespeed = mapobjectscale/4; + } +} + INT32 K_GetDriftAngleOffset(player_t *player) { INT32 a = 0; @@ -10348,6 +10423,8 @@ void K_MoveKartPlayer(player_t *player, boolean onground) K_KartDrift(player, onground); + K_KartSlipdash(player, onground); + // Quick Turning // You can't turn your kart when you're not moving. // So now it's time to burn some rubber! diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 515c84032..943bdb07c 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -220,6 +220,8 @@ enum player_e player_aizdriftstrat, player_aizdrifttilt, player_aizdriftturn, + player_slipdashcharge, + player_slipdashdir, player_offroad, player_pogospring, player_brakestop, @@ -394,6 +396,8 @@ static const char *const player_opt[] = { "aizdriftstrat", "aizdrifttilt", "aizdriftturn", + "slipdashcharge", + "slipdashdir", "offroad", "pogospring", "brakestop", @@ -682,6 +686,12 @@ static int player_get(lua_State *L) case player_aizdriftturn: lua_pushinteger(L, plr->aizdriftturn); break; + case player_slipdashcharge: + lua_pushfixed(L, plr->slipdashcharge); + break; + case player_slipdashdir: + lua_pushinteger(L, plr->slipdashdir); + break; case player_offroad: lua_pushinteger(L, plr->offroad); break; @@ -1279,6 +1289,12 @@ static int player_set(lua_State *L) case player_aizdriftturn: plr->aizdriftturn = luaL_checkinteger(L, 3); break; + case player_slipdashcharge: + plr->slipdashcharge = luaL_checkfixed(L, 3); + break; + case player_slipdashdir: + plr->slipdashdir = luaL_checkinteger(L, 3); + break; case player_offroad: plr->offroad = luaL_checkinteger(L, 3); break; diff --git a/src/p_saveg.c b/src/p_saveg.c index d05c02553..b7a6f91e4 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -259,6 +259,8 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITESINT8(save->p, players[i].aizdriftstrat); WRITEINT32(save->p, players[i].aizdrifttilt); WRITEINT32(save->p, players[i].aizdriftturn); + WRITEFIXED(save->p, players[i].slipdashcharge); + WRITESINT8(save->p, players[i].slipdashdir); WRITEFIXED(save->p, players[i].offroad); WRITEFIXED(save->p, players[i].tiregrease); @@ -573,6 +575,8 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].aizdriftstrat = READSINT8(save->p); players[i].aizdrifttilt = READINT32(save->p); players[i].aizdriftturn = READINT32(save->p); + players[i].slipdashcharge = READFIXED(save->p); + players[i].slipdashdir = READSINT8(save->p); players[i].offroad = READFIXED(save->p); players[i].tiregrease = READFIXED(save->p);