diff --git a/src/k_collide.c b/src/k_collide.c index dcedbcd09..24f9a0eaf 100644 --- a/src/k_collide.c +++ b/src/k_collide.c @@ -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 diff --git a/src/k_collide.h b/src/k_collide.h index 367855e14..8eeb20a4b 100644 --- a/src/k_collide.h +++ b/src/k_collide.h @@ -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); diff --git a/src/k_kart.c b/src/k_kart.c index de6f05a19..155d67d24 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -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; } diff --git a/src/p_local.h b/src/p_local.h index 4903d0726..95e5882bc 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -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; }; diff --git a/src/p_map.c b/src/p_map.c index 3bb96994e..a183c2da8 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -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; diff --git a/src/p_mobj.c b/src/p_mobj.c index 61a5fe3a6..3c645ccc3 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -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))