Merge branch 'battle-fixups' into 'master'

Battle fixups

Closes #1382

See merge request kart-krew-dev/ring-racers-internal!2647
This commit is contained in:
Oni VelocitOni 2025-06-27 00:47:41 +00:00
commit 82ea18865c
7 changed files with 65 additions and 27 deletions

View file

@ -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

View file

@ -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))
@ -1158,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)
{

View file

@ -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);
@ -1180,20 +1183,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 (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);
@ -4565,12 +4554,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)
@ -4578,6 +4571,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);
@ -4615,7 +4610,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);
@ -10380,6 +10377,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)
@ -14722,7 +14721,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)
{

View file

@ -118,6 +118,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);

View file

@ -65,9 +65,10 @@ 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;
player->mo->flags |= MF_NOCLIPTHING;
Obj_SpawnPowerUpSpinner(player->mo, powerup, BATTLE_POWERUP_VFX_TIME);
g_darkness.start = leveltime;

View file

@ -3104,6 +3104,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!

View file

@ -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--;
}