Fix orbi/jawz bumps, ensure bumpcode always runs

The game manually runs P_TryMove and P_SlideMove for orbiting items, so
putting it in P_BounceMove is not gonna work
This commit is contained in:
GenericHeroGuy 2025-11-23 17:11:19 +01:00
parent bb77cfb227
commit d897f6fee9
6 changed files with 70 additions and 75 deletions

View file

@ -40,7 +40,7 @@ angle_t K_GetCollideAngle(mobj_t *t1, mobj_t *t2)
}
// This/Other Item Damage
static void K_ItemDamage(mobj_t *t1, mobj_t *t2, boolean clash)
void K_ItemDamage(mobj_t *t1, mobj_t *t2, boolean clash)
{
if (t1->eflags & MFE_VERTICALFLIP)
t1->z -= t1->height;
@ -98,6 +98,7 @@ boolean K_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2)
{
// Melt item
S_StartSound(t2, sfx_s3k43);
damageitem = true;
}
else
{
@ -105,9 +106,8 @@ boolean K_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2)
P_DamageMobj(t2, t1, t1->target, 1, DMG_WIPEOUT);
K_SetHitThing(t2, t1);
S_StartSound(t2, sfx_s3k7b);
//damageitem = true; // delayed until K_KartBouncing, don't mess with the orbi's momentum
}
damageitem = true;
}
else if (t2->type == MT_ORBINAUT || t2->type == MT_JAWZ || t2->type == MT_JAWZ_DUD
|| t2->type == MT_ORBINAUT_SHIELD || t2->type == MT_JAWZ_SHIELD

View file

@ -9,6 +9,7 @@ extern "C" {
#endif
angle_t K_GetCollideAngle(mobj_t *t1, mobj_t *t2);
void K_ItemDamage(mobj_t *t1, mobj_t *t2, boolean clash);
boolean K_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2);
boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2);
boolean K_EggItemCollide(mobj_t *t1, mobj_t *t2);

View file

@ -822,14 +822,7 @@ boolean K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean sol
return false;
}
if (mobj2->health <= 0 && (mobj2->type == MT_ORBINAUT || mobj2->type == MT_ORBINAUT_SHIELD
|| mobj2->type == MT_JAWZ || mobj2->type == MT_JAWZ_SHIELD || mobj2->type == MT_JAWZ_DUD))
{
// dead orbis and jawz are supposed to have a momz of 0 here
// but K_KartBouncing now runs AFTER K_ItemDamage
mobj1->momz = 0;
}
else if (bounce == true && mass2 > 0) // Perform a Goomba Bounce.
if (bounce == true && mass2 > 0) // Perform a Goomba Bounce.
{
mobj1->momz = -mobj1->momz;
}

View file

@ -484,6 +484,7 @@ struct TryMoveResult_t
line_t *line;
mobj_t *mo;
boolean blockingmo; // set if PIT_CheckThing blocked the move (mo may still be set!)
boolean slideout; // set if bouncing failed, and the moving mobj should slide
vector2_t normal;
};

View file

@ -2725,14 +2725,9 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff, Try
sector_t *oldsector = thing->subsector->sector;
// Is the move OK?
if (increment_move(thing, x, y, allowdropoff, result) == false)
{
if (result != NULL)
{
result->success = false;
}
return false;
}
boolean success = increment_move(thing, x, y, allowdropoff, result);
if (!success)
goto exit;
// If it's a pushable object, check if anything is
// standing on top and move it, too.
@ -2849,12 +2844,64 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff, Try
numspechitint = 0U;
exit:
if (result != NULL)
result->success = success;
if (result != NULL && !P_MobjWasRemoved(result->mo)) // object bounce
{
result->success = true;
mobj_t *mo1 = thing, *mo2 = result->mo;
boolean bounce = false;
if (mo2->player != NULL)
{
if (P_IsObjectOnGround(mo2) && mo1->momz < 0)
{
bounce = true;
}
else if (P_IsObjectOnGround(mo1) && mo2->momz < 0)
{
bounce = true;
mo1 = result->mo;
mo2 = thing;
}
}
else switch (mo2->type)
{
case MT_BLUEROBRA:
case MT_BLUEROBRA_HEAD:
case MT_SMK_PIPE:
case MT_SMK_THWOMP:
case MT_SMK_ICEBLOCK:
break;
default:
case MT_KART_LEFTOVER:
bounce = P_IsObjectOnGround(mo2) && mo1->momz < 0;
break;
}
// no more special logic! if you want a solid bounce, return BMIT_ABORT
if (!K_KartBouncing(mo1, mo2, bounce, result->blockingmo))
{
// if you can't bounce, slide off of blocking mobjs instead of getting trapped
if (result->blockingmo)
result->slideout = true;
}
if (mo1->type == MT_ORBINAUT || mo1->type == MT_ORBINAUT_SHIELD
|| mo1->type == MT_JAWZ || mo1->type == MT_JAWZ_SHIELD || mo1->type == MT_JAWZ_DUD)
{
K_ItemDamage(mo1, mo2, false);
}
else if (mo2->type == MT_ORBINAUT || mo2->type == MT_ORBINAUT_SHIELD
|| mo2->type == MT_JAWZ || mo2->type == MT_JAWZ_SHIELD || mo2->type == MT_JAWZ_DUD)
{
K_ItemDamage(mo2, mo1, false);
}
}
return true;
return success;
}
boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y, TryMoveResult_t *result)
@ -3330,8 +3377,7 @@ void P_SlideMove(mobj_t *mo, TryMoveResult_t *result)
if (P_MobjWasRemoved(mo))
return;
if (result == NULL)
return;
I_Assert(result != NULL);
if (result->mo && mo->z + mo->height > result->mo->z && mo->z < result->mo->z + result->mo->height)
{
@ -3508,7 +3554,7 @@ papercollision:
// Bounce move, for players.
//
static void P_BouncePlayerMove(mobj_t *mo, TryMoveResult_t *result, boolean slideout)
static void P_BouncePlayerMove(mobj_t *mo, TryMoveResult_t *result)
{
fixed_t mmomx = 0, mmomy = 0;
fixed_t oldmomx = mo->momx, oldmomy = mo->momy;
@ -3519,10 +3565,9 @@ static void P_BouncePlayerMove(mobj_t *mo, TryMoveResult_t *result, boolean slid
if (mo->player == NULL)
return;
if (result == NULL)
return;
I_Assert(result != NULL);
if (mo->player->spectator || slideout)
if (mo->player->spectator || result->slideout)
{
P_SlideMove(mo, result);
return;
@ -3625,60 +3670,19 @@ static void P_BouncePlayerMove(mobj_t *mo, TryMoveResult_t *result, boolean slid
void P_BounceMove(mobj_t *mo, TryMoveResult_t *result)
{
fixed_t mmomx = 0, mmomy = 0;
boolean slideout = false;
if (P_MobjWasRemoved(mo))
return;
if (result != NULL && !P_MobjWasRemoved(result->mo)) // object bounce
{
mobj_t *mo1 = mo, *mo2 = result->mo;
boolean bounce = false;
if (mo2->player != NULL)
{
if (P_IsObjectOnGround(mo2) && mo1->momz < 0)
{
bounce = true;
}
else if (P_IsObjectOnGround(mo1) && mo2->momz < 0)
{
bounce = true;
mo1 = result->mo;
mo2 = mo;
}
}
else switch (mo2->type)
{
case MT_BLUEROBRA:
case MT_BLUEROBRA_HEAD:
case MT_SMK_PIPE:
case MT_SMK_THWOMP:
case MT_SMK_ICEBLOCK:
break;
default:
case MT_KART_LEFTOVER:
bounce = P_IsObjectOnGround(mo2) && mo1->momz < 0;
break;
}
// no more special logic! if you want a solid bounce, return BMIT_ABORT
if (!K_KartBouncing(mo1, mo2, bounce, result->blockingmo))
{
// if you can't bounce, slide off of blocking mobjs instead of getting trapped
if (result->blockingmo)
slideout = true;
}
}
I_Assert(result != NULL);
if (mo->player)
{
P_BouncePlayerMove(mo, result, slideout);
P_BouncePlayerMove(mo, result);
return;
}
if (mo->eflags & MFE_JUSTBOUNCEDWALL || slideout)
if (mo->eflags & MFE_JUSTBOUNCEDWALL || result->slideout)
{
P_SlideMove(mo, result);
return;

View file

@ -1841,10 +1841,6 @@ void P_XYMovement(mobj_t *mo)
{
// TERRAIN footstep effects.
K_HandleFootstepParticles(mo);
// we still need to bounce off objects even if the move succeeded!
if (!P_MobjWasRemoved(result.mo))
P_BounceMove(mo, &result);
}
if (moved && oldslope && !(mo->flags & MF_NOCLIPHEIGHT))