diff --git a/src/d_player.h b/src/d_player.h index ba491154e..2dfb00652 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -977,6 +977,7 @@ struct player_t angle_t besthanddirection; INT16 incontrol; // -1 to -175 when spinning out or tumbling, 1 to 175 when not. Use to check for combo hits or emergency inputs. + UINT16 progressivethrust; // When getting beat up in GTR_BUMPERS, speed up the longer you've been out of control. boolean markedfordeath; boolean dotrickfx; diff --git a/src/k_kart.c b/src/k_kart.c index 33f622d71..9d117d0ec 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4560,11 +4560,13 @@ void K_BumperInflate(player_t *player) if (!player || P_MobjWasRemoved(player->mo)) return; - if (!(player->mo->health > 1 && gametyperules & GTR_BUMPERS)) + if (!(gametyperules & GTR_BUMPERS)) return; player->bumperinflate = 3; - S_StartSound(player->mo, sfx_cdpcm9); + + if (player->mo->health > 1) + S_StartSound(player->mo, sfx_cdpcm9); } static void K_HandleTumbleBounce(player_t *player) @@ -8801,15 +8803,18 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->hyudorotimer) player->hyudorotimer--; - if (player->bumperinflate && player->mo->health > 1 && player->mo->hitlag == 0) + if (player->bumperinflate && player->mo->hitlag == 0) { + UINT16 cappedthrust = min(player->progressivethrust, THRUSTCAP); + if (player->tumbleBounces && player->tumbleBounces <= TUMBLEBOUNCES) { - player->mo->momz += BUMPER_FLOAT; + player->mo->momz += DAMAGEFLOAT * cappedthrust; + P_Thrust(player->mo, K_MomentumAngle(player->mo), DAMAGETHRUST * cappedthrust / 2); } - else if (player->speed < K_GetKartSpeed(player, false, false)/2) + else { - P_Thrust(player->mo, K_MomentumAngle(player->mo), BUMPER_THRUST); + P_Thrust(player->mo, K_MomentumAngle(player->mo), DAMAGETHRUST * cappedthrust); } player->bumperinflate--; } @@ -8920,12 +8925,15 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->spinouttimer || player->tumbleBounces) { + player->progressivethrust++; if (player->incontrol > 0) player->incontrol = 0; player->incontrol--; } else { + if (player->progressivethrust && leveltime % 3 == 0) + player->progressivethrust--; if (player->incontrol < 0) player->incontrol = 0; player->incontrol++; diff --git a/src/k_kart.h b/src/k_kart.h index 8309bfc08..b60614477 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -37,8 +37,9 @@ Make sure this matches the actual number of states #define INSTAWHIP_TETHERBLOCK (TICRATE*4) #define PUNISHWINDOW (7*TICRATE/10) -#define BUMPER_FLOAT (8*mapobjectscale) -#define BUMPER_THRUST (10*mapobjectscale) +#define DAMAGEFLOAT (FRACUNIT/50) +#define DAMAGETHRUST (FRACUNIT/70) +#define THRUSTCAP (TICRATE*10) #define FLAMESHIELD_MAX (120) diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 875167cb6..616121b21 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -257,6 +257,10 @@ 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,"incontrol")) + lua_pushboolean(L, plr->incontrol); + else if (fastcmp(field,"progressivethrust")) + lua_pushboolean(L, plr->progressivethrust); else if (fastcmp(field,"dotrickfx")) lua_pushboolean(L, plr->dotrickfx); else if (fastcmp(field,"bumperinflate")) @@ -781,6 +785,10 @@ static int player_set(lua_State *L) plr->justDI = luaL_checkinteger(L, 3); else if (fastcmp(field,"flipDI")) plr->flipDI = luaL_checkboolean(L, 3); + else if (fastcmp(field,"incontrol")) + plr->incontrol = luaL_checkinteger(L, 3); + else if (fastcmp(field,"progressivethrust")) + plr->progressivethrust = luaL_checkboolean(L, 3); else if (fastcmp(field,"markedfordeath")) plr->markedfordeath = luaL_checkboolean(L, 3); else if (fastcmp(field,"dotrickfx")) diff --git a/src/p_inter.c b/src/p_inter.c index 62e2d3cef..a074b23fa 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3374,11 +3374,12 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da //P_KillPlayer(player, inflictor, source, damagetype); } - // Have bumpers? Demote wipeout combos to stumble, force the attacker to make a DI read. - if (player->mo->health > 1 && gametyperules & GTR_BUMPERS) + // Death save! On your last hit, no matter what, demote to weakest damage type for one last escape chance. + if (player->mo->health == 2 && damage && gametyperules & GTR_BUMPERS) { - if (type == DMG_WIPEOUT && P_PlayerInPain(player)) - type = DMG_STUMBLE; + S_StartSound(target, sfx_gshc7); + player->flashing = TICRATE; + type = DMG_STUMBLE; } switch (type) diff --git a/src/p_map.c b/src/p_map.c index edd9cd993..182db056c 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -4178,7 +4178,7 @@ static void P_BouncePlayerMove(mobj_t *mo, TryMoveResult_t *result) mo->eflags |= MFE_JUSTBOUNCEDWALL; // Combo avoidance! - if (mo->player && P_PlayerInPain(mo->player) && gametyperules & GTR_BUMPERS && mo->health > 1) + if (mo->player && P_PlayerInPain(mo->player) && gametyperules & GTR_BUMPERS && mo->health == 1) { K_StumblePlayer(mo->player); K_BumperInflate(mo->player); diff --git a/src/p_saveg.c b/src/p_saveg.c index 6fafe80bb..180c6ed0b 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -589,6 +589,7 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEANGLE(save->p, players[i].besthanddirection); WRITEINT16(save->p, players[i].incontrol); + WRITEUINT16(save->p, players[i].progressivethrust); WRITEUINT8(save->p, players[i].markedfordeath); WRITEUINT8(save->p, players[i].dotrickfx); @@ -1164,6 +1165,7 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].besthanddirection = READANGLE(save->p); players[i].incontrol = READINT16(save->p); + players[i].progressivethrust = READUINT16(save->p); players[i].markedfordeath = READUINT8(save->p); players[i].dotrickfx = READUINT8(save->p); diff --git a/src/sounds.c b/src/sounds.c index 828f67242..1339fd384 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -1448,7 +1448,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"gshc4", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"gshc5", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"gshc6", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"gshc7", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"gshc7", false, 64, 16, -1, NULL, 0, -1, -1, LUMPERROR, ""}, //x8away {"gshc8", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"gshc9", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"gshca", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},