From dd0b9a97fcc4c1cce7ea1df0c6b03bbfc8107abc Mon Sep 17 00:00:00 2001 From: Antonio Martinez Date: Wed, 25 Jun 2025 14:59:22 -0400 Subject: [PATCH 1/5] Longer bufo invinc, decreases always --- src/k_powerup.cpp | 2 +- src/p_user.c | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/k_powerup.cpp b/src/k_powerup.cpp index 2efd94b84..bf3cad8ed 100644 --- a/src/k_powerup.cpp +++ b/src/k_powerup.cpp @@ -65,7 +65,7 @@ void K_GivePowerUp(player_t* player, kartitems_t powerup, tic_t time) } S_StartSound(NULL, sfx_gsha7l); - player->flashing = 2*TICRATE; + player->flashing = 3*TICRATE; player->mo->hitlag += BATTLE_POWERUP_VFX_TIME; player->powerupVFXTimer = BATTLE_POWERUP_VFX_TIME; Obj_SpawnPowerUpSpinner(player->mo, powerup, BATTLE_POWERUP_VFX_TIME); diff --git a/src/p_user.c b/src/p_user.c index 74a4be388..019050b9b 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4564,9 +4564,7 @@ void P_PlayerThink(player_t *player) // Strength counts up to diminish fade. if (player->flashing && player->flashing < UINT16_MAX && - (player->spectator || !P_PlayerInPain(player)) && - // Battle: flashing tics do not decrease in the air - (!(gametyperules & GTR_BUMPERS) || P_IsObjectOnGround(player->mo))) + (player->spectator || !P_PlayerInPain(player))) { player->flashing--; } From 4e23ebe95b778cefac784d8c2198367f35473ce6 Mon Sep 17 00:00:00 2001 From: Antonio Martinez Date: Wed, 25 Jun 2025 15:33:45 -0400 Subject: [PATCH 2/5] Players with bubbleblowup aren't guarding --- src/k_kart.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/k_kart.c b/src/k_kart.c index 5ac1ba0ad..f9e7b6b8c 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1185,6 +1185,11 @@ boolean K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2) boolean guard1 = K_PlayerGuard(mobj1->player); boolean guard2 = K_PlayerGuard(mobj2->player); + if (mobj1->player->bubbleblowup) + guard1 = false; + if (mobj2->player->bubbleblowup) + guard2 = false; + if (guard1 && guard2) K_DoPowerClash(mobj1, mobj2); else if (guard1) @@ -4556,12 +4561,16 @@ void K_DoPowerClash(mobj_t *t1, mobj_t *t2) { UINT8 lag1 = 5; UINT8 lag2 = 5; + boolean stripbubble = (gametyperules & GTR_BUMPERS); + // short-circuit instashield for vfx visibility if (t1->player) { t1->player->instashield = 1; t1->player->speedpunt += 20; lag1 -= min(lag1, t1->player->speedpunt/10); + if (stripbubble && t1->player->curshield == KSHIELD_BUBBLE) + K_PopBubbleShield(t1->player); } if (t2->player) @@ -4569,6 +4578,8 @@ void K_DoPowerClash(mobj_t *t1, mobj_t *t2) { t2->player->instashield = 1; t2->player->speedpunt += 20; lag2 -= min(lag1, t2->player->speedpunt/10); + if (stripbubble && t2->player->curshield == KSHIELD_BUBBLE) + K_PopBubbleShield(t2->player); } S_StartSound(t1, sfx_parry); From 72c680b54f25e7e416375b3cf4a62877073fb5b7 Mon Sep 17 00:00:00 2001 From: Antonio Martinez Date: Wed, 25 Jun 2025 15:57:34 -0400 Subject: [PATCH 3/5] In Battle, pop bubble on damage or clash and increase cooldown --- src/k_collide.cpp | 14 ++++++++++++-- src/k_kart.c | 7 +++++-- src/k_kart.h | 2 ++ 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/k_collide.cpp b/src/k_collide.cpp index 0de68598c..443b8fcbc 100644 --- a/src/k_collide.cpp +++ b/src/k_collide.cpp @@ -885,18 +885,28 @@ boolean K_BubbleShieldCollide(mobj_t *t1, mobj_t *t2) thing = oldthing; P_SetTarget(&g_tm.thing, oldg_tm.thing);*/ + boolean hit = false; + if (K_KartBouncing(t2, t1->target) == true) { if (t2->player && t1->target && t1->target->player) { - K_PvPTouchDamage(t2, t1->target); + hit = K_PvPTouchDamage(t2, t1->target); } // Don't play from t1 else it gets cut out... for some reason. S_StartSound(t2, sfx_s3k44); } - return true; + if (hit && (gametyperules & GTR_BUMPERS)) + { + K_PopBubbleShield(t1->target->player); + return false; + } + else + { + return true; + } } if (K_BubbleShieldCanReflect(t1, t2)) diff --git a/src/k_kart.c b/src/k_kart.c index f9e7b6b8c..be13789bf 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -72,8 +72,11 @@ // comeback is Battle Mode's karma comeback, also bool // mapreset is set when enough players fill an empty server -static void K_PopBubbleShield(player_t *player) +void K_PopBubbleShield(player_t *player) { + if (player->curshield != KSHIELD_BUBBLE) + return; + S_StartSound(player->mo, sfx_kc31); K_StripItems(player); K_AddHitLag(player->mo, 4, false); @@ -14566,7 +14569,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) S_StartSound(player->mo, sfx_s3k75); player->bubbleblowup++; - player->bubblecool = player->bubbleblowup*4; + player->bubblecool = player->bubbleblowup * (gametyperules & GTR_BUMPERS ? 6 : 4); if (player->bubbleblowup > bubbletime*2) { diff --git a/src/k_kart.h b/src/k_kart.h index 9d9f3fdf8..6b810d6c6 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -111,6 +111,8 @@ Make sure this matches the actual number of states angle_t K_ReflectAngle(angle_t angle, angle_t against, fixed_t maxspeed, fixed_t yourspeed); +void K_PopBubbleShield(player_t *player); + boolean K_IsDuelItem(mobjtype_t type); boolean K_DuelItemAlwaysSpawns(mapthing_t *mt); boolean K_InRaceDuel(void); From dfaece7d3d74a08b9cc27000f5a3fe44a5d100ab Mon Sep 17 00:00:00 2001 From: Antonio Martinez Date: Wed, 25 Jun 2025 16:26:56 -0400 Subject: [PATCH 4/5] Do guardbreak in touchdamage, guarantee punish (PF2_ALWAYSDAMAGED) --- src/d_player.h | 11 ++++++----- src/k_collide.cpp | 21 +++++++++++++++++++++ src/k_kart.c | 21 ++------------------- src/p_inter.c | 6 ++++++ 4 files changed, 35 insertions(+), 24 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 16339b32a..74ff42cdc 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -135,11 +135,12 @@ typedef enum typedef enum { - PF2_SELFMUTE = 1<<1, - PF2_SELFDEAFEN = 1<<2, - PF2_SERVERMUTE = 1<<3, - PF2_SERVERDEAFEN = 1<<4, - PF2_STRICTFASTFALL = 1<<5, + PF2_SELFMUTE = 1<<1, + PF2_SELFDEAFEN = 1<<2, + PF2_SERVERMUTE = 1<<3, + PF2_SERVERDEAFEN = 1<<4, + PF2_STRICTFASTFALL = 1<<5, + PF2_ALWAYSDAMAGED = 1<<6, } pflags2_t; typedef enum diff --git a/src/k_collide.cpp b/src/k_collide.cpp index 443b8fcbc..0392e0133 100644 --- a/src/k_collide.cpp +++ b/src/k_collide.cpp @@ -1168,6 +1168,27 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2) return false; } + + boolean guard1 = K_PlayerGuard(t1->player); + boolean guard2 = K_PlayerGuard(t2->player); + + // Bubble Shield physically extends past guard when inflated, + // makes some sense to suppress this behavior + if (t1->player->bubbleblowup) + guard1 = false; + if (t2->player->bubbleblowup) + guard2 = false; + + if (guard1 && guard2) + K_DoPowerClash(t1, t2); + else if (guard1) + K_DoGuardBreak(t1, t2); + else if (guard2) + K_DoGuardBreak(t2, t1); + + if (guard1 || guard2) + return false; + // Clash instead of damage if both parties have any of these conditions auto canClash = [](mobj_t *t1, mobj_t *t2) { diff --git a/src/k_kart.c b/src/k_kart.c index be13789bf..41087e46c 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1182,25 +1182,6 @@ boolean K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2) K_SpawnBumpForObjs(mobj1, mobj2); - if (mobj1->type == MT_PLAYER && mobj2->type == MT_PLAYER - && !mobj1->player->powerupVFXTimer && !mobj2->player->powerupVFXTimer) - { - boolean guard1 = K_PlayerGuard(mobj1->player); - boolean guard2 = K_PlayerGuard(mobj2->player); - - if (mobj1->player->bubbleblowup) - guard1 = false; - if (mobj2->player->bubbleblowup) - guard2 = false; - - if (guard1 && guard2) - K_DoPowerClash(mobj1, mobj2); - else if (guard1) - K_DoGuardBreak(mobj1, mobj2); - else if (guard2) - K_DoGuardBreak(mobj2, mobj1); - } - K_PlayerJustBumped(mobj1->player); K_PlayerJustBumped(mobj2->player); @@ -4620,7 +4601,9 @@ void K_DoGuardBreak(mobj_t *t1, mobj_t *t2) { angle_t thrangle = R_PointToAngle2(t2->x, t2->y, t1->x, t1->y); P_Thrust(t1, thrangle, 7*mapobjectscale); + t1->player->pflags2 |= PF2_ALWAYSDAMAGED; P_DamageMobj(t1, t2, t2, 1, DMG_TUMBLE); + t1->player->pflags2 &= ~PF2_ALWAYSDAMAGED; clash = P_SpawnMobj((t1->x/2) + (t2->x/2), (t1->y/2) + (t2->y/2), (t1->z/2) + (t2->z/2), MT_GUARDBREAK); diff --git a/src/p_inter.c b/src/p_inter.c index 04a05ce4c..251dd917a 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3094,6 +3094,12 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da invincible = false; } + if (player->pflags2 && PF2_ALWAYSDAMAGED) + { + invincible = false; + clash = false; + } + // TODO: doing this from P_DamageMobj limits punting to objects that damage the player. // And it may be kind of yucky. // But this is easier than accounting for every condition in PIT_CheckThing! From 6a327ffb286ab9b23cafcf0821534307b02b1456 Mon Sep 17 00:00:00 2001 From: Antonio Martinez Date: Thu, 26 Jun 2025 20:28:14 -0400 Subject: [PATCH 5/5] Absolutely fuck it, noclipthing during powerupvfx --- src/k_kart.c | 2 ++ src/k_powerup.cpp | 1 + 2 files changed, 3 insertions(+) diff --git a/src/k_kart.c b/src/k_kart.c index 41087e46c..2f4b9ac7e 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -10310,6 +10310,8 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->powerupVFXTimer > 0) { player->powerupVFXTimer--; + if (player->powerupVFXTimer == 0) + player->mo->flags &= ~MF_NOCLIPTHING; } if (player->dotrickfx && !player->mo->hitlag) diff --git a/src/k_powerup.cpp b/src/k_powerup.cpp index bf3cad8ed..38ece8439 100644 --- a/src/k_powerup.cpp +++ b/src/k_powerup.cpp @@ -68,6 +68,7 @@ void K_GivePowerUp(player_t* player, kartitems_t powerup, tic_t time) player->flashing = 3*TICRATE; player->mo->hitlag += BATTLE_POWERUP_VFX_TIME; player->powerupVFXTimer = BATTLE_POWERUP_VFX_TIME; + player->mo->flags |= MF_NOCLIPTHING; Obj_SpawnPowerUpSpinner(player->mo, powerup, BATTLE_POWERUP_VFX_TIME); g_darkness.start = leveltime;