diff --git a/src/d_player.h b/src/d_player.h index c62494b51..c17b8d48d 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -698,6 +698,7 @@ struct player_t INT32 nullHitlag; // Numbers of tics of hitlag that will ultimately be ignored by subtracting from hitlag UINT8 wipeoutslow; // Timer before you slowdown when getting wiped out UINT8 justbumped; // Prevent players from endlessly bumping into each other + UINT8 noEbrakeMagnet; // Briefly disable 2.2 responsive ebrake if you're bumped by another player. UINT8 tumbleBounces; UINT16 tumbleHeight; // In *mobjscaled* fracunits, or mfu, not raw fu UINT8 justDI; // Turn-lockout timer to briefly prevent unintended turning after DI, resets when actionable or no input @@ -746,6 +747,7 @@ struct player_t UINT8 tripwireState; // see tripwirestate_t UINT8 tripwirePass; // see tripwirepass_t UINT16 tripwireLeniency; // When reaching a state that lets you go thru tripwire, you get an extra second leniency after it ends to still go through it. + UINT8 fakeBoost; // Some items need to grant tripwire pass briefly, even when their effect is thrust/instathrust. This is a fake boost type to control that. itemroulette_t itemRoulette; // Item roulette data @@ -809,6 +811,7 @@ struct player_t fixed_t trickboostpower; // Save the rough speed multiplier. Used for upwards tricks. UINT8 trickboostdecay; // used to know how long you've waited UINT8 trickboost; // Trick boost. This one is weird and has variable speed. Dear god. + UINT8 tricklock; // Input safety for 2.2 lenient tricks. UINT8 dashRingPullTics; // Timer during which the player is pulled towards a dash ring UINT8 dashRingPushTics; // Timer during which the player displays effects and has no gravity after being thrust by a dash ring diff --git a/src/doomstat.h b/src/doomstat.h index 38902b1d1..a94d0de82 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -797,6 +797,7 @@ extern INT32 itemtime; extern INT32 bubbletime; extern INT32 comebacktime; extern INT32 bumptime; +extern INT32 ebraketime; extern INT32 greasetics; extern INT32 wipeoutslowtime; extern INT32 wantedreduce; diff --git a/src/g_game.c b/src/g_game.c index 079b7bbab..c946f3eb0 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -265,6 +265,7 @@ INT32 itemtime = 8*TICRATE; INT32 bubbletime = TICRATE/2; INT32 comebacktime = 3*TICRATE; INT32 bumptime = 6; +INT32 ebraketime = TICRATE; INT32 greasetics = 3*TICRATE; INT32 wipeoutslowtime = 20; INT32 wantedreduce = 5*TICRATE; diff --git a/src/k_hitlag.c b/src/k_hitlag.c index c12cbf67c..27f8dc7e6 100644 --- a/src/k_hitlag.c +++ b/src/k_hitlag.c @@ -72,7 +72,7 @@ void K_AddHitLag(mobj_t *mo, INT32 tics, boolean fromDamage) Return:- N/A --------------------------------------------------*/ -static void K_SpawnSingleHitLagSpark( +void K_SpawnSingleHitLagSpark( mobj_t *parent, vector3_t *offset, fixed_t scale, UINT8 tics, UINT8 pause, diff --git a/src/k_hitlag.h b/src/k_hitlag.h index 2a14eb44d..62ea19bda 100644 --- a/src/k_hitlag.h +++ b/src/k_hitlag.h @@ -60,6 +60,7 @@ void K_AddHitLag(mobj_t *mo, INT32 tics, boolean fromDamage); --------------------------------------------------*/ void K_SetHitLagForObjects(mobj_t *victim, mobj_t *inflictor, mobj_t *source, INT32 tics, boolean fromDamage); +void K_SpawnSingleHitLagSpark(mobj_t *parent, vector3_t *offset, fixed_t scale, UINT8 tics, UINT8 pause, skincolornum_t color); #ifdef __cplusplus diff --git a/src/k_hud.cpp b/src/k_hud.cpp index c4853b4db..8766cd951 100644 --- a/src/k_hud.cpp +++ b/src/k_hud.cpp @@ -237,6 +237,7 @@ patch_t *kp_button_up[2]; patch_t *kp_button_down[2]; patch_t *kp_button_right[2]; patch_t *kp_button_left[2]; +patch_t *kp_button_dpad[2]; static void K_LoadButtonGraphics(patch_t *kp[2], int letter) { @@ -910,6 +911,7 @@ void K_LoadKartHUDGraphics(void) K_LoadButtonGraphics(kp_button_down, 'K'); K_LoadButtonGraphics(kp_button_right, 'L'); K_LoadButtonGraphics(kp_button_left, 'M'); + K_LoadButtonGraphics(kp_button_dpad, 'T'); } // For the item toggle menu diff --git a/src/k_hud.h b/src/k_hud.h index dea1e5a98..a4e92c728 100644 --- a/src/k_hud.h +++ b/src/k_hud.h @@ -92,6 +92,7 @@ extern patch_t *kp_button_up[2]; extern patch_t *kp_button_down[2]; extern patch_t *kp_button_right[2]; extern patch_t *kp_button_left[2]; +extern patch_t *kp_button_dpad[2]; extern patch_t *kp_eggnum[6]; extern patch_t *kp_facenum[MAXPLAYERS+1]; diff --git a/src/k_kart.c b/src/k_kart.c index fa5b2d089..8af1933f0 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -840,6 +840,7 @@ static void K_PlayerJustBumped(player_t *player) } player->justbumped = bumptime; + player->noEbrakeMagnet = ebraketime; player->spindash = 0; // If spinouttimer is not set yet but could be set later, @@ -983,12 +984,14 @@ boolean K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2) if (mobj1->player && mobj1->player->justbumped && !K_JustBumpedException(mobj2)) { mobj1->player->justbumped = bumptime; + mobj1->player->noEbrakeMagnet = ebraketime; return false; } if (mobj2->player && mobj2->player->justbumped && !K_JustBumpedException(mobj1)) { mobj2->player->justbumped = bumptime; + mobj2->player->noEbrakeMagnet = ebraketime; return false; } @@ -3001,7 +3004,8 @@ tripwirepass_t K_TripwirePassConditions(const player_t *player) if ( player->flamedash || - ((player->speed > K_PlayerTripwireSpeedThreshold(player)) && player->tripwireReboundDelay == 0) + ((player->speed > K_PlayerTripwireSpeedThreshold(player)) && player->tripwireReboundDelay == 0) || + player->fakeBoost ) return TRIPWIRE_BOOST; @@ -3369,7 +3373,17 @@ fixed_t K_GetSpindashChargeSpeed(const player_t *player) // more speed for higher weight & speed // Tails = +16.94%, Fang = +34.94%, Mighty = +34.94%, Metal = +43.61% // (can be higher than this value when overcharged) - const fixed_t val = (10*FRACUNIT/277) + (((player->kartspeed + player->kartweight) + 2) * FRACUNIT) / 45; + + // The above comment is now strictly incorrect and I can't be assed to do the math properly. + // 2.2 introduces a power fudge to compensate for the removal of spindash overcharge. -Tyron + fixed_t val = (10*FRACUNIT/277) + (((player->kartspeed + player->kartweight) + 2) * FRACUNIT) / 45; + + // 2.2 - Improved Spindash + if (!G_CompatLevel(0x000A)) + { + if (gametyperules & GTR_CIRCUIT) + val = 5 * val / 4; + } // Old behavior before desperation spindash // return (gametyperules & GTR_CLOSERPLAYERS) ? (4 * val) : val; @@ -4226,7 +4240,7 @@ static fixed_t K_TumbleZ(mobj_t *mo, fixed_t input) return FixedMul(input, -gravityAdjust); } -void K_TumblePlayer(player_t *player, mobj_t *inflictor, mobj_t *source) +void K_TumblePlayer(player_t *player, mobj_t *inflictor, mobj_t *source, boolean soften) { (void)source; @@ -4250,11 +4264,18 @@ void K_TumblePlayer(player_t *player, mobj_t *inflictor, mobj_t *source) if (inflictor && !P_MobjWasRemoved(inflictor)) { - const fixed_t addHeight = FixedHypot(FixedHypot(inflictor->momx, inflictor->momy) / 2, FixedHypot(player->mo->momx, player->mo->momy) / 2); + fixed_t addHeight = FixedHypot(FixedHypot(inflictor->momx, inflictor->momy) / 2, FixedHypot(player->mo->momx, player->mo->momy) / 2); + if (soften) + addHeight = FixedMul(addHeight, 6*FRACUNIT/10); player->tumbleHeight += (addHeight / player->mo->scale); player->tumbleHeight = min(200, player->tumbleHeight); } + if (soften) + { + player->tumbleBounces = 2; + } + S_StartSound(player->mo, sfx_s3k9b); player->mo->momz = K_TumbleZ(player->mo, player->tumbleHeight * FRACUNIT); @@ -4834,7 +4855,7 @@ void K_ApplyTripWire(player_t *player, tripwirestate_t state) { // We are either softlocked or wildly misbehaving. Stop that! if (state == TRIPSTATE_BLOCKED && player->tripwireReboundDelay && (player->speed > 5 * K_GetKartSpeed(player, false, false))) - K_TumblePlayer(player, NULL, NULL); + K_TumblePlayer(player, NULL, NULL, false); if (state == TRIPSTATE_PASSED) { @@ -4862,6 +4883,8 @@ void K_ApplyTripWire(player_t *player, tripwirestate_t state) { S_StartSound(player->mo, sfx_kc40); player->tripwireReboundDelay = 60; + if (player->curshield == KSHIELD_BUBBLE) + player->tripwireReboundDelay *= 2; } player->tripwireState = state; @@ -4875,7 +4898,7 @@ void K_ApplyTripWire(player_t *player, tripwirestate_t state) if (state == TRIPSTATE_PASSED && player->spinouttimer && player->speed > K_PlayerTripwireSpeedThreshold(player)) { - K_TumblePlayer(player, NULL, NULL); + K_TumblePlayer(player, NULL, NULL, false); } player->tripwireUnstuck += 10; @@ -8816,6 +8839,18 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->ringdelay) player->ringdelay--; + if (player->trickpanel == TRICKSTATE_READY) + { + if (!player->throwdir && !cmd->turning) + player->tricklock = TICRATE/10; + else if (player->tricklock) + player->tricklock--; + } + else + { + player->tricklock = 0; + } + if (P_PlayerInPain(player)) { player->ringboost = 0; @@ -9086,6 +9121,9 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->hyudorotimer) player->hyudorotimer--; + if (player->fakeBoost) + player->fakeBoost--; + if (player->bumperinflate && player->mo->hitlag == 0) { fixed_t thrustdelta = MAXCOMBOTHRUST - MINCOMBOTHRUST; @@ -9139,6 +9177,9 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->justbumped > 0) player->justbumped--; + if (player->noEbrakeMagnet > 0) + player->noEbrakeMagnet--; + if (player->defenseLockout) { player->instaWhipCharge = 0; @@ -10437,10 +10478,14 @@ INT16 K_GetKartTurnValue(const player_t *player, INT16 turnvalue) return 0; } - if (player->trickpanel == TRICKSTATE_READY || player->trickpanel == TRICKSTATE_FORWARD) + // Staff ghosts - direction-only trickpanel behavior + if (G_CompatLevel(0x000A) || K_PlayerUsesBotMovement(player)) { - // Forward trick or rising from trickpanel - return 0; + if (player->trickpanel == TRICKSTATE_READY || player->trickpanel == TRICKSTATE_FORWARD) + { + // Forward trick or rising from trickpanel + return 0; + } } if (player->justDI > 0) @@ -10599,6 +10644,18 @@ INT16 K_GetKartTurnValue(const player_t *player, INT16 turnvalue) turnfixed /= 2; } + // 2.2 - Presteering allowed in trickpanels + if (!G_CompatLevel(0x000A) && !K_PlayerUsesBotMovement(player)) + { + if (player->trickpanel == TRICKSTATE_READY || player->trickpanel == TRICKSTATE_FORWARD) + { + // Forward trick or rising from trickpanel + turnfixed /= 2; + if (player->tricklock) + turnfixed /= (player->tricklock/2 + 1); + } + } + return (turnfixed / FRACUNIT); } @@ -11791,6 +11848,18 @@ static void K_KartSpindash(player_t *player) player->pflags &= ~PF_NOFASTFALL; return; } + else + { + // 2.2 - More responsive ebrake + if (!G_CompatLevel(0x000A)) + { + if (onGround && player->noEbrakeMagnet == 0 && (FixedHypot(player->mo->momx, player->mo->momy) < 20*player->mo->scale)) + { + P_Thrust(player->mo, K_MomentumAngleReal(player->mo) + ANGLE_180, FixedHypot(player->mo->momx, player->mo->momy)/8); + } + } + + } // Handle fast falling behaviors first. if (player->respawn.state != RESPAWNST_NONE) @@ -11876,7 +11945,17 @@ static void K_KartSpindash(player_t *player) // Intentionally a lop-sided trade-off, so the game doesn't become // Funky Kong's Ring Racers. - P_PlayerRingBurst(player, 1); + // 2.2 - No extended ring debt for recovery spindash + if (G_CompatLevel(0x000A)) + { + P_PlayerRingBurst(player, 1); + } + else + { + if (player->rings > 0) + P_PlayerRingBurst(player, 1); + } + } if (chargetime > 0) @@ -11951,6 +12030,33 @@ boolean K_FastFallBounce(player_t *player) player->ignoreAirtimeLeniency = max(player->ignoreAirtimeLeniency, TICRATE); bounce += 3 * mapobjectscale; + + UINT8 i; + UINT8 numplayers = 0; + if (gametyperules & GTR_CIRCUIT) + { + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i] && !players[i].spectator) + numplayers++; + } + } + else + { + numplayers = 1; // solo behavior + } + + if (player->position == 1 && player->positiondelay <= 0 && numplayers != 1) + { + S_StartSound(player->mo, sfx_kc31); + K_StripItems(player); + K_AddHitLag(player->mo, 4, false); + vector3_t offset = { 0, 0, 0 }; + K_SpawnSingleHitLagSpark(player->mo, &offset, player->mo->scale*2, 4, 0, player->skincolor); + } + + if (player->tripwireReboundDelay) + bounce /= 2; } else { @@ -13084,9 +13190,9 @@ void K_MoveKartPlayer(player_t *player, boolean onground) if (player->throwdir == -1) { P_InstaThrust(player->mo, player->mo->angle, player->speed + (80 * mapobjectscale)); - player->wavedashboost += TICRATE; // Just for keeping speed briefly vs. tripwire etc. + player->wavedashboost += TICRATE; player->wavedashpower = FRACUNIT; - // If this doesn't turn out to be reliable, I'll change it to directly set leniency or something. + player->fakeBoost = TICRATE/2; } K_PlayAttackTaunt(player->mo); player->bubbleblowup = 0; @@ -13166,6 +13272,10 @@ void K_MoveKartPlayer(player_t *player, boolean onground) player->mo, player->mo->angle, FixedMul((50*player->mo->scale), K_GetKartGameSpeedScalar(gamespeed)) ); + + player->wavedashboost += TICRATE; + player->wavedashpower = FRACUNIT; + player->fakeBoost = TICRATE/3; S_StopSoundByID(player->mo, sfx_fshld1); S_StopSoundByID(player->mo, sfx_fshld0); @@ -13408,6 +13518,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) player->tumbleHeight = 30; // Base tumble bounce height player->trickpanel = TRICKSTATE_NONE; P_SetPlayerMobjState(player->mo, S_KART_SPINOUT); + K_AddMessageForPlayer(player, "Press + to trick!", true, false); if (player->itemflags & (IF_ITEMOUT|IF_EGGMANOUT)) { //K_PopPlayerShield(player); // shield is just being yeeted, don't pop @@ -13424,6 +13535,15 @@ void K_MoveKartPlayer(player_t *player, boolean onground) INT16 aimingcompare = abs(cmd->throwdir) - abs(cmd->turning); + // 2.2 - Pre-steering trickpanels + if (!G_CompatLevel(0x000A) && !K_PlayerUsesBotMovement(player)) + { + if (!(player->cmd.buttons & BT_ACCELERATE)) + { + aimingcompare = 0; + } + } + // Uses cmd->turning over steering intentionally. #define TRICKTHRESHOLD (KART_FULLTURN/2) if (aimingcompare < -TRICKTHRESHOLD) // side trick @@ -13654,12 +13774,24 @@ void K_MoveKartPlayer(player_t *player, boolean onground) player->trickboostdecay = 0; } - // Wait until we let go off the control stick to remove the delay - // buttons must be neutral after the initial trick delay. This prevents weirdness where slight nudges after blast off would send you flying. - if ((player->pflags & PF_TRICKDELAY) && !player->throwdir && !cmd->turning && (player->tricktime >= TRICKDELAY)) + // 2.2 - Lenient trickpanels + if (G_CompatLevel(0x000A) || K_PlayerUsesBotMovement(player)) { - player->pflags &= ~PF_TRICKDELAY; + // Wait until we let go off the control stick to remove the delay + // buttons must be neutral after the initial trick delay. This prevents weirdness where slight nudges after blast off would send you flying. + if ((player->pflags & PF_TRICKDELAY) && !player->throwdir && !cmd->turning && (player->tricktime >= TRICKDELAY)) + { + player->pflags &= ~PF_TRICKDELAY; + } } + else + { + if ((player->pflags & PF_TRICKDELAY) && !(player->cmd.buttons & BT_ACCELERATE) && (player->tricktime >= TRICKDELAY)) + { + player->pflags &= ~PF_TRICKDELAY; + } + } + } K_KartDrift(player, onground); diff --git a/src/k_kart.h b/src/k_kart.h index 09c2d46d4..6556138e1 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -137,7 +137,7 @@ void K_BattleAwardHit(player_t *player, player_t *victim, mobj_t *inflictor, UIN void K_RemoveGrowShrink(player_t *player); boolean K_IsBigger(mobj_t *compare, mobj_t *other); void K_SpinPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 type); -void K_TumblePlayer(player_t *player, mobj_t *inflictor, mobj_t *source); +void K_TumblePlayer(player_t *player, mobj_t *inflictor, mobj_t *source, boolean soften); void K_TumbleInterrupt(player_t *player); angle_t K_StumbleSlope(angle_t angle, angle_t pitch, angle_t roll); void K_StumblePlayer(player_t *player); diff --git a/src/k_menudraw.c b/src/k_menudraw.c index c920f1bb6..5cbd79f73 100644 --- a/src/k_menudraw.c +++ b/src/k_menudraw.c @@ -8833,7 +8833,16 @@ void M_DrawSoundTest(void) if (soundtest.current->source) V_DrawThinString(x+1, (y += 10), 0, soundtest.current->source); if (soundtest.current->composers) - V_DrawThinString(x+1, (y += 10), 0, soundtest.current->composers); + { + char *wrappedcomposers = V_ScaledWordWrap( + (BASEVIDWIDTH - ((x+1)*2)) << FRACBITS, + FRACUNIT, FRACUNIT, FRACUNIT, + 0, TINY_FONT, + soundtest.current->composers + ); + V_DrawThinString(x+1, (y += 10), 0, wrappedcomposers); + Z_Free(wrappedcomposers); + } } else { diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 181a80b45..d282b99a5 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -3169,6 +3169,7 @@ static int lib_kTumblePlayer(lua_State *L) player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); mobj_t *inflictor = NULL; mobj_t *source = NULL; + boolean soften = false; NOHUD if (!player) return LUA_ErrInvalid(L, "player_t"); @@ -3176,7 +3177,8 @@ static int lib_kTumblePlayer(lua_State *L) inflictor = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); if (!lua_isnone(L, 3) && lua_isuserdata(L, 3)) source = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); - K_TumblePlayer(player, inflictor, source); + soften = lua_optboolean(L, 4); + K_TumblePlayer(player, inflictor, source, soften); return 0; } diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index e3ecb502a..d0ba8e582 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -250,6 +250,8 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->wipeoutslow); else if (fastcmp(field,"justbumped")) lua_pushinteger(L, plr->justbumped); + else if (fastcmp(field,"noebrakemagnet")) + lua_pushinteger(L, plr->noEbrakeMagnet); else if (fastcmp(field,"tumblebounces")) lua_pushinteger(L, plr->tumbleBounces); else if (fastcmp(field,"tumbleheight")) @@ -342,6 +344,8 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->tripwireState); else if (fastcmp(field,"tripwirepass")) lua_pushinteger(L, plr->tripwirePass); + else if (fastcmp(field,"fakeboost")) + lua_pushinteger(L, plr->fakeBoost); else if (fastcmp(field,"tripwireleniency")) lua_pushinteger(L, plr->tripwireLeniency); else if (fastcmp(field,"tripwirerebounddelay")) @@ -476,6 +480,8 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->trickboostdecay); else if (fastcmp(field,"trickboost")) lua_pushinteger(L, plr->trickboost); + else if (fastcmp(field,"tricklock")) + lua_pushinteger(L, plr->tricklock); else if (fastcmp(field,"dashringpulltics")) lua_pushinteger(L, plr->dashRingPullTics); else if (fastcmp(field,"dashringpushtics")) @@ -802,6 +808,8 @@ static int player_set(lua_State *L) plr->wipeoutslow = luaL_checkinteger(L, 3); else if (fastcmp(field,"justbumped")) plr->justbumped = luaL_checkinteger(L, 3); + else if (fastcmp(field,"noebrakemagnet")) + plr->noEbrakeMagnet = luaL_checkinteger(L, 3); else if (fastcmp(field,"tumblebounces")) plr->tumbleBounces = luaL_checkinteger(L, 3); else if (fastcmp(field,"tumbleheight")) @@ -892,6 +900,8 @@ static int player_set(lua_State *L) plr->tripwireState = luaL_checkinteger(L, 3); else if (fastcmp(field,"tripwirepass")) plr->tripwirePass = luaL_checkinteger(L, 3); + else if (fastcmp(field,"fakeboost")) + plr->fakeBoost = luaL_checkinteger(L, 3); else if (fastcmp(field,"tripwireleniency")) plr->tripwireLeniency = luaL_checkinteger(L, 3); else if (fastcmp(field,"tripwirerebounddelay")) @@ -1026,6 +1036,8 @@ static int player_set(lua_State *L) plr->trickboostdecay = luaL_checkinteger(L, 3); else if (fastcmp(field,"trickboost")) plr->trickboost = luaL_checkinteger(L, 3); + else if (fastcmp(field,"tricklock")) + plr->tricklock = luaL_checkinteger(L, 3); else if (fastcmp(field,"dashringpulltics")) plr->dashRingPullTics = luaL_checkinteger(L, 3); else if (fastcmp(field,"dashringpushtics")) diff --git a/src/objects/dlzrocket.c b/src/objects/dlzrocket.c index 2094bf774..36547c369 100644 --- a/src/objects/dlzrocket.c +++ b/src/objects/dlzrocket.c @@ -196,6 +196,7 @@ void Obj_playerDLZRocket(player_t *p) } if ((p->dlzrocket > 10 && (P_IsObjectOnGround(p->mo) || p->mo->eflags & MFE_JUSTBOUNCEDWALL)) - || p->spinouttimer || p->wipeoutslow || p->tumbleHeight) + || p->spinouttimer || p->wipeoutslow || p->tumbleBounces + || p->respawn.state != RESPAWNST_NONE) Obj_DLZRocketDismount(p); } diff --git a/src/objects/rideroid.c b/src/objects/rideroid.c index 4492212fa..7670944bd 100644 --- a/src/objects/rideroid.c +++ b/src/objects/rideroid.c @@ -314,7 +314,7 @@ void Obj_RideroidThink(mobj_t *mo) // if we hit a wall or get hit, get off of the rideroid. - if (pmo->eflags & MFE_JUSTBOUNCEDWALL || P_PlayerInPain(p)) + if (pmo->eflags & MFE_JUSTBOUNCEDWALL || P_PlayerInPain(p) || p->respawn.state != RESPAWNST_NONE) { Obj_explodeRideroid(mo); return; diff --git a/src/p_inter.c b/src/p_inter.c index dc51f2d84..884091c2d 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3145,6 +3145,8 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da damage = 0; } + boolean hitFromInvinc = false; + // Sting and stumble shouldn't be rewarding Battle hits. if (type == DMG_STING || type == DMG_STUMBLE) { @@ -3162,6 +3164,8 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da { tic_t kinvextend; + hitFromInvinc = true; + if (gametyperules & GTR_CLOSERPLAYERS) kinvextend = 2*TICRATE; else @@ -3284,7 +3288,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da ringburst = 0; break; case DMG_TUMBLE: - K_TumblePlayer(player, inflictor, source); + K_TumblePlayer(player, inflictor, source, hitFromInvinc); ringburst = 10; break; case DMG_EXPLODE: @@ -3328,7 +3332,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da if (gametyperules & GTR_BUMPERS) player->spheres = min(player->spheres + 10, 40); - if ((hardhit == true) || cv_kartdebughuddrop.value) + if ((hardhit == true && !hitFromInvinc) || cv_kartdebughuddrop.value) { K_DropItems(player); } diff --git a/src/p_saveg.c b/src/p_saveg.c index 4dab0507b..bef745fdb 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -434,6 +434,7 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEINT32(save->p, players[i].nullHitlag); WRITEUINT8(save->p, players[i].wipeoutslow); WRITEUINT8(save->p, players[i].justbumped); + WRITEUINT8(save->p, players[i].noEbrakeMagnet); WRITEUINT8(save->p, players[i].tumbleBounces); WRITEUINT16(save->p, players[i].tumbleHeight); @@ -483,6 +484,7 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEUINT8(save->p, players[i].tripwireState); WRITEUINT8(save->p, players[i].tripwirePass); WRITEUINT16(save->p, players[i].tripwireLeniency); + WRITEUINT8(save->p, players[i].fakeBoost); WRITESINT8(save->p, players[i].itemtype); WRITEUINT8(save->p, players[i].itemamount); @@ -540,6 +542,7 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEUINT32(save->p, players[i].trickboostpower); WRITEUINT8(save->p, players[i].trickboostdecay); WRITEUINT8(save->p, players[i].trickboost); + WRITEUINT8(save->p, players[i].tricklock); WRITEUINT8(save->p, players[i].dashRingPullTics); WRITEUINT8(save->p, players[i].dashRingPushTics); @@ -1032,6 +1035,7 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].nullHitlag = READINT32(save->p); players[i].wipeoutslow = READUINT8(save->p); players[i].justbumped = READUINT8(save->p); + players[i].noEbrakeMagnet = READUINT8(save->p); players[i].tumbleBounces = READUINT8(save->p); players[i].tumbleHeight = READUINT16(save->p); @@ -1081,6 +1085,7 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].tripwireState = READUINT8(save->p); players[i].tripwirePass = READUINT8(save->p); players[i].tripwireLeniency = READUINT16(save->p); + players[i].fakeBoost = READUINT8(save->p); players[i].itemtype = READSINT8(save->p); players[i].itemamount = READUINT8(save->p); @@ -1138,6 +1143,7 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].trickboostpower = READUINT32(save->p); players[i].trickboostdecay = READUINT8(save->p); players[i].trickboost = READUINT8(save->p); + players[i].tricklock = READUINT8(save->p); players[i].dashRingPullTics = READUINT8(save->p); players[i].dashRingPushTics = READUINT8(save->p); diff --git a/src/s_sound.c b/src/s_sound.c index c1d9a4df2..4369f9250 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -2204,7 +2204,7 @@ void S_LoadMusicCredit(void) widthused -= V_ThinStringWidth(credittext, 0); -#define MUSICCREDITAPPEND(field)\ +#define MUSICCREDITAPPEND(field, force)\ if (field)\ {\ work = va(" - %s", field);\ @@ -2212,7 +2212,7 @@ void S_LoadMusicCredit(void) if (worklen <= len)\ {\ workwidth = V_ThinStringWidth(work, 0);\ - if (widthused >= workwidth)\ + if (force || widthused >= workwidth)\ {\ strncat(credittext, work, len);\ len -= worklen;\ @@ -2221,8 +2221,8 @@ void S_LoadMusicCredit(void) }\ } - MUSICCREDITAPPEND(def->author); - MUSICCREDITAPPEND(def->source); + MUSICCREDITAPPEND(def->author, true); + MUSICCREDITAPPEND(def->source, false); #undef MUSICCREDITAPPEND } diff --git a/src/v_draw.cpp b/src/v_draw.cpp index 7914d0a0c..12a05d63c 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -43,6 +43,8 @@ Draw::TextElement& Draw::TextElement::parse(std::string_view raw) BUTTON("right", 0x02), BUTTON("left", 0x03), + BUTTON("dpad", 0x04), + BUTTON("r", 0x07), BUTTON("l", 0x08), BUTTON("start", 0x09), @@ -197,6 +199,7 @@ patch_t** get_button_patch(Draw::Button type, int ver) X(down); X(right); X(left); + X(dpad); #undef X } diff --git a/src/v_draw.hpp b/src/v_draw.hpp index 8d5c8386a..82c60e845 100644 --- a/src/v_draw.hpp +++ b/src/v_draw.hpp @@ -76,6 +76,7 @@ public: down, right, left, + dpad, }; class TextElement diff --git a/src/v_video.cpp b/src/v_video.cpp index 5a9e3c11e..40f2d694e 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -2505,6 +2505,11 @@ static UINT8 V_GetButtonCodeWidth(UINT8 c) x = 14; break; + case 0x04: + // dpad + x = 14; + break; + case 0x0A: case 0x0B: case 0x0C: @@ -2700,6 +2705,8 @@ void V_DrawStringScaled( case 0x02: return {{0, 3, Draw::Button::right}}; case 0x03: return {{0, 3, Draw::Button::left}}; + case 0x04: return {{0, 4, Draw::Button::dpad}}; + case 0x07: return {{0, 2, Draw::Button::r}}; case 0x08: return {{0, 2, Draw::Button::l}};