diff --git a/src/d_player.h b/src/d_player.h index 27767b6cb..cc6687518 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -40,8 +40,7 @@ extern "C" { typedef enum { SF_MACHINE = 1, // Beep boop. Are you a robot? - SF_NOGIBS = 1<<1, // Does this kart smash into pieces? - SF_OLDDEATH = 1<<2, // Kart V1 styled death animation + SF_OLDDEATH = 1<<1, // Kart V1 styled death animation // free up to and including 1<<31 } skinflags_t; diff --git a/src/deh_tables.c b/src/deh_tables.c index e8820039e..c0701085f 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -1005,7 +1005,6 @@ struct int_const_s const INT_CONST[] = { // Character flags (skinflags_t) {"SF_HIRES",0}, {"SF_MACHINE",SF_MACHINE}, - {"SF_NOGIBS",SF_NOGIBS}, {"SF_OLDDEATH",SF_OLDDEATH}, // Sound flags diff --git a/src/info/actions.h b/src/info/actions.h index 365385077..845e8ffee 100644 --- a/src/info/actions.h +++ b/src/info/actions.h @@ -222,4 +222,3 @@ _(A_RoamingShadowThinker, ROAMINGSHADOWTHINKER) _(A_MayonakaArrow, MAYONAKAARROW) _(A_MementosTPParticles, MEMENTOSTPPARTICLES) _(A_ReaperThinker, REAPERTHINKER) -_(A_DeathSpin, DEATHSPIN) diff --git a/src/info/mobjs.h b/src/info/mobjs.h index f35657ba5..368453768 100644 --- a/src/info/mobjs.h +++ b/src/info/mobjs.h @@ -5,8 +5,6 @@ _(UNKNOWN) _(THOK) // Thok! mobj _(SHADOW) // Linkdraw Shadow (for invisible objects) _(PLAYER) -_(KART_LEFTOVER) -_(KART_TIRE) // Enemies _(BLUECRAWLA) // Crawla (Blue) diff --git a/src/info/sprites.h b/src/info/sprites.h index 4723e29cb..b1e373547 100644 --- a/src/info/sprites.h +++ b/src/info/sprites.h @@ -7,8 +7,6 @@ _(UNKN) _(THOK) // Thok! mobj _(PLAY) -_(KART) -_(TIRE) // Enemies _(POSS) // Crawla (Blue) diff --git a/src/info/states.h b/src/info/states.h index d95d856c1..a2a394e28 100644 --- a/src/info/states.h +++ b/src/info/states.h @@ -48,9 +48,6 @@ _(KART_SIGN) // technically the player goes here but it's an infinite tic state _(OBJPLACE_DUMMY) -_(KART_LEFTOVER) -_(KART_TIRE) - // Blue Crawla _(POSS_STND) _(POSS_RUN1) diff --git a/src/k_collide.c b/src/k_collide.c index cf32bd60a..f65383704 100644 --- a/src/k_collide.c +++ b/src/k_collide.c @@ -574,7 +574,6 @@ boolean K_BubbleShieldCanReflect(mobj_t *t1, mobj_t *t2) return (t2->type == MT_ORBINAUT || t2->type == MT_JAWZ || t2->type == MT_JAWZ_DUD || t2->type == MT_BANANA || t2->type == MT_EGGMANITEM || t2->type == MT_BALLHOG || t2->type == MT_SSMINE || t2->type == MT_LANDMINE || t2->type == MT_SINK - || t2->type == MT_KART_LEFTOVER || (t2->type == MT_PLAYER && t1->target != t2)); } diff --git a/src/k_kart.c b/src/k_kart.c index 8787c8cac..0c6ef0ab6 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1960,14 +1960,6 @@ fixed_t K_GetMobjWeight(mobj_t *mobj, mobj_t *against) break; weight = K_PlayerWeight(mobj, against); break; - case MT_KART_LEFTOVER: - weight = 5*FRACUNIT/2; - - if (mobj->extravalue1 > 0) - { - weight = mobj->extravalue1 * (FRACUNIT >> 1); - } - break; case MT_BUBBLESHIELD: weight = K_PlayerWeight(mobj->target, against); break; @@ -7009,7 +7001,7 @@ static void K_MoveHeldObjects(player_t *player) cur->flags &= ~MF_NOCLIPTHING; if (!P_TryMove(cur, player->mo->x + cur->momx, player->mo->y + cur->momy, true, &result)) - P_SlideMove(cur,&result); + P_SlideMoveOLD(cur); if (P_IsObjectOnGround(player->mo)) { diff --git a/src/p_enemy.c b/src/p_enemy.c index b1f5416b4..8242a3f2b 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -11659,9 +11659,3 @@ void A_ReaperThinker(mobj_t *actor) } } } - -void A_DeathSpin(mobj_t *actor) -{ - INT32 locvar1 = var1; - actor->angle += locvar1; -} diff --git a/src/p_inter.c b/src/p_inter.c index 41fb3bfd1..334e1d53d 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1565,88 +1565,9 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget case MT_PLAYER: if (damagetype != DMG_SPECTATOR) { - target->fuse = 2*TICRATE; // timer before mobj disappears from view (even if not an actual player) + target->fuse = TICRATE; target->momx = target->momy = target->momz = 0; - - if (target->player && !(skins[target->player->skin].flags & SF_NOGIBS)) - { - angle_t playerFlingAngle; - angle_t kartFlingAngle; - - if (source && !P_MobjWasRemoved(source)) - { - playerFlingAngle = kartFlingAngle = R_PointToAngle2( - source->x - source->momx, source->y - source->momy, - target->x, target->y - ); - } - else - { - kartFlingAngle = target->angle; - - if (P_RandomByte() & 1) - { - kartFlingAngle -= ANGLE_45; - } - else - { - kartFlingAngle += ANGLE_45; - } - - playerFlingAngle = kartFlingAngle + ANGLE_180; - } - - // Spawn kart frame - mobj_t *kart = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_KART_LEFTOVER); - - if (kart && !P_MobjWasRemoved(kart)) - { - kart->angle = target->angle; - kart->color = target->color; - kart->extravalue1 = target->player->kartweight; - kart->fuse = 2*TICRATE; - - // Copy interp data - kart->old_angle = target->old_angle; - kart->old_x = target->old_x; - kart->old_y = target->old_y; - kart->old_z = target->old_z; - - P_InstaThrust(kart, kartFlingAngle, 1 * kart->scale); - P_SetObjectMomZ(kart, 10*FRACUNIT, false); - - const angle_t aOffset = ANGLE_22h; - - UINT8 i; - angle_t tireAngle; - mobj_t *tire; - - // Spawn tires - tireAngle = kartFlingAngle - ANGLE_90 - ANGLE_22h; - for (i = 0; i < 4; i++) - { - if (i == 2) tireAngle += ANGLE_90; - - tire = P_SpawnMobjFromMobj(kart, 0, 0, 0, MT_KART_TIRE); - tire->fuse = 2*TICRATE; - - tire->angle = tireAngle; - P_InstaThrust(tire, tireAngle, 3 * tire->scale); - P_SetObjectMomZ(tire, 10*FRACUNIT, false); - - tireAngle += (aOffset * 2); - } - } - - P_InstaThrust(target, playerFlingAngle, 4 * target->scale); - P_SetObjectMomZ(target, 14*FRACUNIT, false); - } - - if (target->player && (skins[target->player->skin].flags & SF_OLDDEATH)) - { - P_SetObjectMomZ(target, 14*FRACUNIT, false); - } - + P_SetObjectMomZ(target, 14*FRACUNIT, false); P_PlayDeathSound(target); } break; diff --git a/src/p_local.h b/src/p_local.h index 20d8f3e1d..f3e565321 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -500,6 +500,7 @@ boolean P_Move(mobj_t *actor, fixed_t speed); boolean P_SetOrigin(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z); boolean P_MoveOrigin(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z); void P_SlideMove(mobj_t *mo, TryMoveResult_t *result); +void P_SlideMoveOLD(mobj_t *mo); void P_BounceMove(mobj_t *mo, TryMoveResult_t *result); boolean P_CheckSight(mobj_t *t1, mobj_t *t2); boolean P_TraceBlockingLines(mobj_t *t1, mobj_t *t2); diff --git a/src/p_map.c b/src/p_map.c index e2d06ed34..d258de3c9 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1290,21 +1290,6 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing) return BMIT_CONTINUE; } - else if (thing->type == MT_KART_LEFTOVER) - { - // see if it went over / under - if (g_tm.thing->z > thing->z + thing->height) - return BMIT_CONTINUE; // overhead - if (g_tm.thing->z + g_tm.thing->height < thing->z) - return BMIT_CONTINUE; // underneath - - if (P_IsObjectOnGround(thing) && g_tm.thing->momz < 0) - K_KartBouncing(g_tm.thing, thing, true, false); - else - K_KartBouncing(g_tm.thing, thing, false, false); - - return BMIT_CONTINUE; - } else if (thing->flags & MF_SOLID) { // see if it went over / under @@ -3115,7 +3100,9 @@ static boolean P_ThingHeightClip(mobj_t *thing) // SLIDE MOVE // Allows the player to slide along any angled walls. // +static fixed_t bestslidefrac, secondslidefrac; static line_t *bestslideline; +static line_t *secondslideline; static mobj_t *slidemo; static fixed_t tmxmove, tmymove; @@ -3185,6 +3172,41 @@ static void P_PlayerHitBounceLine(line_t *ld, vector2_t* normal) } } +static void P_PlayerHitBounceLineOLD(line_t *ld) +{ + INT32 side; + angle_t lineangle; + fixed_t movelen; + fixed_t x, y; + + side = P_PointOnLineSide(slidemo->x, slidemo->y, ld); + lineangle = R_PointToAngle2(0, 0, ld->dx, ld->dy)-ANGLE_90; + + if (side == 1) + lineangle += ANGLE_180; + + lineangle >>= ANGLETOFINESHIFT; + + movelen = P_AproxDistance(tmxmove, tmymove); + + if (slidemo->player && movelen < (15*mapobjectscale)) + movelen = (15*mapobjectscale); + + x = FixedMul(movelen, FINECOSINE(lineangle)); + y = FixedMul(movelen, FINESINE(lineangle)); + + if (ld && P_IsLineTripWire(ld)) + { + tmxmove = FixedMul(x, FRACUNIT+(FRACUNIT/2)); + tmymove = FixedMul(y, FRACUNIT+(FRACUNIT/2)); + } + else + { + tmxmove += x; + tmymove += y; + } +} + // // P_HitBounceLine // @@ -3226,7 +3248,6 @@ static void P_HitBounceLine(line_t *ld) deltaangle = R_PointToAngle2(0, 0, tmxmove, tmymove); } -/* static boolean PTR_LineIsBlocking(line_t *li) { opening_t open = {0}; @@ -3252,9 +3273,7 @@ static boolean PTR_LineIsBlocking(line_t *li) return false; } -*/ -/* static boolean PTR_SlideTraverse(intercept_t *in) { line_t *li; @@ -3284,7 +3303,6 @@ static boolean PTR_SlideTraverse(intercept_t *in) return false; // stop } -*/ static void P_CheckLavaWall(mobj_t *mo, sector_t *sec) { @@ -3420,7 +3438,31 @@ void P_SlideMove(mobj_t *mo, TryMoveResult_t *result) bestslideline = result->line; if (bestslideline == NULL) + { + if (K_IsMissileOrKartItem(mo)) + { + if (cv_showgremlins.value) + { + // debug + mobj_t*x = P_SpawnMobj(mo->x, mo->y, mo->z, MT_THOK); + x->frame = FF_FULLBRIGHT | FF_ADD; + x->renderflags = RF_ALWAYSONTOP; + x->color = SKINCOLOR_RED; + + CONS_Printf( + "SLIDE GREMLIN: leveltime=%u x=%f y=%f z=%f", + leveltime, + FixedToFloat(mo->x), + FixedToFloat(mo->y), + FixedToFloat(mo->z) + ); + } + + // We were not succesful, try the old version. + P_SlideMoveOLD(mo); + } return; + } if (bestslideline && mo->player && bestslideline->sidenum[1] != 0xffff) { @@ -3484,12 +3526,390 @@ papercollision: } while(tmxmove || tmymove); } +void P_SlideMoveOLD(mobj_t *mo) +{ + fixed_t leadx, leady, trailx, traily, newx, newy; + INT16 hitcount = 0; + boolean success = false; + + boolean papercol = false; + vertex_t v1, v2; // fake vertexes + static line_t junk; // fake linedef + + memset(&junk, 0x00, sizeof(junk)); + + I_Assert(!P_MobjWasRemoved(mo)); + + if (g_tm.hitthing && mo->z + mo->height > g_tm.hitthing->z && mo->z < g_tm.hitthing->z + g_tm.hitthing->height) + { + // Don't mess with your momentum if it's a pushable object. Pushables do their own crazy things already. + if (g_tm.hitthing->flags & MF_PUSHABLE) + return; + + if (g_tm.hitthing->flags & MF_PAPERCOLLISION) + { + fixed_t cosradius, sinradius, num, den; + + // trace along the three leading corners + if (mo->momx > 0) + { + leadx = mo->x + mo->radius; + trailx = mo->x - mo->radius; + } + else + { + leadx = mo->x - mo->radius; + trailx = mo->x + mo->radius; + } + + if (mo->momy > 0) + { + leady = mo->y + mo->radius; + traily = mo->y - mo->radius; + } + else + { + leady = mo->y - mo->radius; + traily = mo->y + mo->radius; + } + + papercol = true; + slidemo = mo; + bestslideline = &junk; + + cosradius = FixedMul(g_tm.hitthing->radius, FINECOSINE(g_tm.hitthing->angle>>ANGLETOFINESHIFT)); + sinradius = FixedMul(g_tm.hitthing->radius, FINESINE(g_tm.hitthing->angle>>ANGLETOFINESHIFT)); + + v1.x = g_tm.hitthing->x - cosradius; + v1.y = g_tm.hitthing->y - sinradius; + v2.x = g_tm.hitthing->x + cosradius; + v2.y = g_tm.hitthing->y + sinradius; + + // Can we box collision our way into smooth movement..? + if (sinradius && mo->y + mo->radius <= min(v1.y, v2.y)) + { + mo->momy = 0; + P_TryMove(mo, mo->x + mo->momx, min(v1.y, v2.y) - mo->radius, true, NULL); + return; + } + else if (sinradius && mo->y - mo->radius >= max(v1.y, v2.y)) + { + mo->momy = 0; + P_TryMove(mo, mo->x + mo->momx, max(v1.y, v2.y) + mo->radius, true, NULL); + return; + } + else if (cosradius && mo->x + mo->radius <= min(v1.x, v2.x)) + { + mo->momx = 0; + P_TryMove(mo, min(v1.x, v2.x) - mo->radius, mo->y + mo->momy, true, NULL); + return; + } + else if (cosradius && mo->x - mo->radius >= max(v1.x, v2.x)) + { + mo->momx = 0; + P_TryMove(mo, max(v1.x, v2.x) + mo->radius, mo->y + mo->momy, true, NULL); + return; + } + + // nope, gotta fuck around with a fake linedef! + junk.v1 = &v1; + junk.v2 = &v2; + junk.dx = 2*cosradius; // v2.x - v1.x; + junk.dy = 2*sinradius; // v2.y - v1.y; + + junk.slopetype = !cosradius ? ST_VERTICAL : !sinradius ? ST_HORIZONTAL : + ((sinradius > 0) == (cosradius > 0)) ? ST_POSITIVE : ST_NEGATIVE; + + bestslidefrac = FRACUNIT+1; + + den = FixedMul(junk.dy>>8, mo->momx) - FixedMul(junk.dx>>8, mo->momy); + + if (!den) + bestslidefrac = 0; + else + { + fixed_t frac; + #define P_PaperTraverse(startx, starty) \ + num = FixedMul((v1.x - leadx)>>8, junk.dy) + FixedMul((leady - v1.y)>>8, junk.dx); \ + frac = FixedDiv(num, den); \ + if (frac < bestslidefrac) \ + bestslidefrac = frac + P_PaperTraverse(leadx, leady); + P_PaperTraverse(trailx, leady); + P_PaperTraverse(leadx, traily); + #undef dowork + } + + goto papercollision; + } + + // Thankfully box collisions are a lot simpler than arbitrary lines. There's only four possible cases. + if (mo->y + mo->radius <= g_tm.hitthing->y - g_tm.hitthing->radius) + { + mo->momy = 0; + P_TryMove(mo, mo->x + mo->momx, g_tm.hitthing->y - g_tm.hitthing->radius - mo->radius, true, NULL); + } + else if (mo->y - mo->radius >= g_tm.hitthing->y + g_tm.hitthing->radius) + { + mo->momy = 0; + P_TryMove(mo, mo->x + mo->momx, g_tm.hitthing->y + g_tm.hitthing->radius + mo->radius, true, NULL); + } + else if (mo->x + mo->radius <= g_tm.hitthing->x - g_tm.hitthing->radius) + { + mo->momx = 0; + P_TryMove(mo, g_tm.hitthing->x - g_tm.hitthing->radius - mo->radius, mo->y + mo->momy, true, NULL); + } + else if (mo->x - mo->radius >= g_tm.hitthing->x + g_tm.hitthing->radius) + { + mo->momx = 0; + P_TryMove(mo, g_tm.hitthing->x + g_tm.hitthing->radius + mo->radius, mo->y + mo->momy, true, NULL); + } + else + mo->momx = mo->momy = 0; + return; + } + + slidemo = mo; + bestslideline = NULL; + + retry: + if ((++hitcount == 3) || papercol) + { + if (!P_MobjWasRemoved(mo)) + { + // the move must have hit the middle, so stairstep + if (!P_TryMove(mo, mo->x, mo->y + mo->momy, true, NULL)) //Allow things to drop off. + P_TryMove(mo, mo->x + mo->momx, mo->y, true, NULL); + } + return; + } + + // trace along the three leading corners + if (mo->momx > 0) + { + leadx = mo->x + mo->radius; + trailx = mo->x - mo->radius; + } + else + { + leadx = mo->x - mo->radius; + trailx = mo->x + mo->radius; + } + + if (mo->momy > 0) + { + leady = mo->y + mo->radius; + traily = mo->y - mo->radius; + } + else + { + leady = mo->y - mo->radius; + traily = mo->y + mo->radius; + } + + bestslidefrac = FRACUNIT+1; + + P_PathTraverse(leadx, leady, leadx + mo->momx, leady + mo->momy, + PT_ADDLINES, PTR_SlideTraverse); + P_PathTraverse(trailx, leady, trailx + mo->momx, leady + mo->momy, + PT_ADDLINES, PTR_SlideTraverse); + P_PathTraverse(leadx, traily, leadx + mo->momx, traily + mo->momy, + PT_ADDLINES, PTR_SlideTraverse); + + if (bestslideline && mo->player && bestslideline->sidenum[1] != 0xffff) + { + sector_t *sec = P_PointOnLineSide(mo->x, mo->y, bestslideline) ? bestslideline->frontsector : bestslideline->backsector; + P_CheckLavaWall(mo, sec); + } + +papercollision: + // move up to the wall + if (bestslidefrac == FRACUNIT+1) + { + if (!P_MobjWasRemoved(mo)) + { + // the move must have hit the middle, so stairstep + if (!P_TryMove(mo, mo->x, mo->y + mo->momy, true, NULL)) //Allow things to drop off. + P_TryMove(mo, mo->x + mo->momx, mo->y, true, NULL); + } + return; + } + + // fudge a bit to make sure it doesn't hit + bestslidefrac -= 0x800; + if (bestslidefrac > 0) + { + newx = FixedMul(mo->momx, bestslidefrac); + newy = FixedMul(mo->momy, bestslidefrac); + + if (!P_TryMove(mo, mo->x + newx, mo->y + newy, true, NULL)) + { + if (!P_MobjWasRemoved(mo)) + { + if (!P_TryMove(mo, mo->x, mo->y + mo->momy, true, NULL)) //Allow things to drop off. + P_TryMove(mo, mo->x + mo->momx, mo->y, true, NULL); + } + return; + } + if (P_MobjWasRemoved(mo)) + return; + } + + // Now continue along the wall. + // First calculate remainder. + bestslidefrac = FRACUNIT - (bestslidefrac+0x800); + + if (bestslidefrac > FRACUNIT) + bestslidefrac = FRACUNIT; + + if (bestslidefrac <= 0) + return; + + tmxmove = FixedMul(mo->momx, bestslidefrac); + tmymove = FixedMul(mo->momy, bestslidefrac); + + P_HitSlideLine(bestslideline); // clip the moves + + mo->momx = tmxmove; + mo->momy = tmymove; + + const fixed_t tmradius = mo->radius > 8 ? mo->radius : 8; + + do { + if (tmxmove > tmradius) { + newx = mo->x + tmradius; + tmxmove -= tmradius; + } else if (tmxmove < -tmradius) { + newx = mo->x - tmradius; + tmxmove += tmradius; + } else { + newx = mo->x + tmxmove; + tmxmove = 0; + } + if (tmymove > tmradius) { + newy = mo->y + tmradius; + tmymove -= tmradius; + } else if (tmymove < -tmradius) { + newy = mo->y - tmradius; + tmymove += tmradius; + } else { + newy = mo->y + tmymove; + tmymove = 0; + } + if (!P_TryMove(mo, newx, newy, true, NULL)) { + if (success || P_MobjWasRemoved(mo)) + return; // Good enough!! + else + goto retry; + } + if (P_MobjWasRemoved(mo)) + return; + success = true; + } while(tmxmove || tmymove); +} + // // P_BouncePlayerMove // // Bounce move, for players. // +static void P_BouncePlayerMoveOLD(mobj_t *mo) +{ + fixed_t leadx, leady; + fixed_t trailx, traily; + fixed_t mmomx = 0, mmomy = 0; + fixed_t oldmomx = mo->momx, oldmomy = mo->momy; + + if (!mo->player) + return; + + slidemo = mo; + + mmomx = mo->player->rmomx; + mmomy = mo->player->rmomy; + + // trace along the three leading corners + if (mo->momx > 0) + { + leadx = mo->x + mo->radius; + trailx = mo->x - mo->radius; + } + else + { + leadx = mo->x - mo->radius; + trailx = mo->x + mo->radius; + } + + if (mo->momy > 0) + { + leady = mo->y + mo->radius; + traily = mo->y - mo->radius; + } + else + { + leady = mo->y - mo->radius; + traily = mo->y + mo->radius; + } + + bestslidefrac = FRACUNIT + 1; + + P_PathTraverse(leadx, leady, leadx + mmomx, leady + mmomy, PT_ADDLINES, PTR_SlideTraverse); + P_PathTraverse(trailx, leady, trailx + mmomx, leady + mmomy, PT_ADDLINES, PTR_SlideTraverse); + P_PathTraverse(leadx, traily, leadx + mmomx, traily + mmomy, PT_ADDLINES, PTR_SlideTraverse); + + // Now continue along the wall. + // First calculate remainder. + bestslidefrac = FRACUNIT - bestslidefrac; + + if (bestslidefrac > FRACUNIT) + bestslidefrac = FRACUNIT; + + if (bestslidefrac <= 0) + return; + + if (mo->eflags & MFE_JUSTBOUNCEDWALL) // Stronger push-out + { + tmxmove = mmomx; + tmymove = mmomy; + } + else + { + tmxmove = FixedMul(mmomx, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); + tmymove = FixedMul(mmomy, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); + } + + if (bestslideline && P_IsLineTripWire(bestslideline)) + { + // TRIPWIRE CANNOT BE MADE NONBOUNCY + K_ApplyTripWire(mo->player, TRIPSTATE_BLOCKED); + } + else + { + // Some walls aren't bouncy even if you are + if (bestslideline && (bestslideline->flags & ML_NOTBOUNCY)) + { + // SRB2Kart: Non-bouncy line! + P_SlideMoveOLD(mo); + return; + } + + K_SpawnBumpEffect(mo); + } + + P_PlayerHitBounceLineOLD(bestslideline); + mo->eflags |= MFE_JUSTBOUNCEDWALL; + + mo->momx = tmxmove; + mo->momy = tmymove; + mo->player->cmomx = tmxmove; + mo->player->cmomy = tmymove; + + if (!P_TryMove(mo, mo->x + tmxmove, mo->y + tmymove, true, NULL)) { + P_TryMove(mo, mo->x - oldmomx, mo->y - oldmomy, true, NULL); + } +} + static void P_BouncePlayerMove(mobj_t *mo, TryMoveResult_t *result) { fixed_t mmomx = 0, mmomy = 0; @@ -3502,7 +3922,9 @@ static void P_BouncePlayerMove(mobj_t *mo, TryMoveResult_t *result) return; if (result == NULL) + { return; + } if (mo->player->spectator) { @@ -3527,25 +3949,38 @@ static void P_BouncePlayerMove(mobj_t *mo, TryMoveResult_t *result) mo->player->pogospring = 0; } + if (G_CompatLevel(0x0002)) + { + P_BouncePlayerMoveOLD(mo); + return; + } + slidemo = mo; bestslideline = result->line; - if (bestslideline == NULL && cv_showgremlins.value) + if (bestslideline == NULL) { - // debug - mobj_t*x = P_SpawnMobj(mo->x, mo->y, mo->z, MT_THOK); - x->frame = FF_FULLBRIGHT | FF_ADD; - x->renderflags = RF_ALWAYSONTOP; - x->color = SKINCOLOR_RED; + if (cv_showgremlins.value) + { + // debug + mobj_t*x = P_SpawnMobj(mo->x, mo->y, mo->z, MT_THOK); + x->frame = FF_FULLBRIGHT | FF_ADD; + x->renderflags = RF_ALWAYSONTOP; + x->color = SKINCOLOR_RED; - CONS_Printf( - "GREMLIN: leveltime=%u x=%f y=%f z=%f angle=%f\n", - leveltime, - FixedToFloat(mo->x), - FixedToFloat(mo->y), - FixedToFloat(mo->z), - AngleToFloat(R_PointToAngle2(0, 0, oldmomx, oldmomy)) - ); + CONS_Printf( + "BOUNCEPLAYER GREMLIN: leveltime=%u x=%f y=%f z=%f angle=%f\n", + leveltime, + FixedToFloat(mo->x), + FixedToFloat(mo->y), + FixedToFloat(mo->z), + AngleToFloat(R_PointToAngle2(0, 0, oldmomx, oldmomy)) + ); + } + + // We were not succesful, try the old version. + P_BouncePlayerMoveOLD(mo); + return; } if (mo->eflags & MFE_JUSTBOUNCEDWALL) // Stronger push-out @@ -3599,6 +4034,149 @@ static void P_BouncePlayerMove(mobj_t *mo, TryMoveResult_t *result) // // The momx / momy move is bad, so try to bounce off a wall. // + +static void P_BounceMoveOLD(mobj_t *mo) +{ + fixed_t leadx, leady; + fixed_t trailx, traily; + fixed_t newx, newy; + INT32 hitcount; + fixed_t mmomx = 0, mmomy = 0; + + slidemo = mo; + hitcount = 0; + + do + { + if (++hitcount == 3) + goto bounceback; // don't loop forever + + if (mo->player) + { + mmomx = mo->player->rmomx; + mmomy = mo->player->rmomy; + } + else + { + mmomx = mo->momx; + mmomy = mo->momy; + } + + // trace along the three leading corners + if (mo->momx > 0) + { + leadx = mo->x + mo->radius; + trailx = mo->x - mo->radius; + } + else + { + leadx = mo->x - mo->radius; + trailx = mo->x + mo->radius; + } + + if (mo->momy > 0) + { + leady = mo->y + mo->radius; + traily = mo->y - mo->radius; + } + else + { + leady = mo->y - mo->radius; + traily = mo->y + mo->radius; + } + + bestslidefrac = FRACUNIT + 1; + + P_PathTraverse(leadx, leady, leadx + mmomx, leady + mmomy, PT_ADDLINES, PTR_SlideTraverse); + P_PathTraverse(trailx, leady, trailx + mmomx, leady + mmomy, PT_ADDLINES, PTR_SlideTraverse); + P_PathTraverse(leadx, traily, leadx + mmomx, traily + mmomy, PT_ADDLINES, PTR_SlideTraverse); + + // move up to the wall + if (bestslidefrac == FRACUNIT + 1) + { + // the move must have hit the middle, so bounce straight back +bounceback: + if (P_TryMove(mo, mo->x - mmomx, mo->y - mmomy, true, NULL)) + { + mo->momx *= -1; + mo->momy *= -1; + mo->momx = FixedMul(mo->momx, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); + mo->momy = FixedMul(mo->momy, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); + + if (mo->player) + { + mo->player->cmomx *= -1; + mo->player->cmomy *= -1; + mo->player->cmomx = FixedMul(mo->player->cmomx, + (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); + mo->player->cmomy = FixedMul(mo->player->cmomy, + (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); + } + } + return; + } + + // fudge a bit to make sure it doesn't hit + bestslidefrac -= 0x800; + if (bestslidefrac > 0) + { + newx = FixedMul(mmomx, bestslidefrac); + newy = FixedMul(mmomy, bestslidefrac); + + if (!P_TryMove(mo, mo->x + newx, mo->y + newy, true, NULL)) + { + if (P_MobjWasRemoved(mo)) + return; + goto bounceback; + } + } + + // Now continue along the wall. + // First calculate remainder. + bestslidefrac = FRACUNIT - bestslidefrac; + + if (bestslidefrac > FRACUNIT) + bestslidefrac = FRACUNIT; + + if (bestslidefrac <= 0) + return; + + if (mo->type == MT_SHELL) + { + tmxmove = mmomx; + tmymove = mmomy; + } + else if (mo->type == MT_THROWNBOUNCE) + { + tmxmove = FixedMul(mmomx, (FRACUNIT - (FRACUNIT>>6) - (FRACUNIT>>5))); + tmymove = FixedMul(mmomy, (FRACUNIT - (FRACUNIT>>6) - (FRACUNIT>>5))); + } + else if (mo->type == MT_THROWNGRENADE || mo->type == MT_CYBRAKDEMON_NAPALM_BOMB_LARGE) + { + // Quickly decay speed as it bounces + tmxmove = FixedDiv(mmomx, 2*FRACUNIT); + tmymove = FixedDiv(mmomy, 2*FRACUNIT); + } + else + { + tmxmove = FixedMul(mmomx, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); + tmymove = FixedMul(mmomy, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); + } + + P_HitBounceLine(bestslideline); // clip the moves + + mo->momx = tmxmove; + mo->momy = tmymove; + + if (mo->player) + { + mo->player->cmomx = tmxmove; + mo->player->cmomy = tmymove; + } + } + while (!P_TryMove(mo, mo->x + tmxmove, mo->y + tmymove, true, NULL) && !P_MobjWasRemoved(mo)); +} + void P_BounceMove(mobj_t *mo, TryMoveResult_t *result) { fixed_t mmomx = 0, mmomy = 0; @@ -3625,7 +4203,30 @@ void P_BounceMove(mobj_t *mo, TryMoveResult_t *result) bestslideline = result->line; if (bestslideline == NULL) + { + if (K_IsMissileOrKartItem(mo)) + { + if (cv_showgremlins.value) + { + // debug + mobj_t*x = P_SpawnMobj(mo->x, mo->y, mo->z, MT_THOK); + x->frame = FF_FULLBRIGHT | FF_ADD; + x->renderflags = RF_ALWAYSONTOP; + x->color = SKINCOLOR_RED; + + CONS_Printf( + "BOUNCE GREMLIN: leveltime=%u x=%f y=%f z=%f\n", + leveltime, + FixedToFloat(mo->x), + FixedToFloat(mo->y), + FixedToFloat(mo->z)); + } + + // We were not succesful, try the old version. + P_BounceMoveOLD(mo); + } return; + } if (mo->type == MT_SHELL) { diff --git a/src/p_mobj.c b/src/p_mobj.c index 56f9c8588..07b10a815 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7940,7 +7940,7 @@ static boolean P_MobjDeadThink(mobj_t *mobj) } else // Apply gravity to fall downwards. { - P_SetObjectMomZ(mobj, -2*FRACUNIT/3, true); + P_SetObjectMomZ(mobj, -3*FRACUNIT/2, true); if (mobj->player && (skins[mobj->player->skin].flags & SF_OLDDEATH)) { @@ -11171,9 +11171,6 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) mobj->color = BALLOONCOLORS[P_RandomKey(sizeof(BALLOONCOLORS))]; } break; - case MT_KART_LEFTOVER: - mobj->color = SKINCOLOR_RED; - break; case MT_REDRING: // Make MT_REDRING red by default mobj->color = skincolor_redring; break; diff --git a/src/r_skins.c b/src/r_skins.c index 009a61452..c66368531 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -746,7 +746,7 @@ static void R_LoadSkinSprites(UINT16 wadnum, UINT16 *lump, UINT16 *lastlump, ski R_AddKartFaces(skin); - skin->flags |= SF_OLDDEATH|SF_NOGIBS; + skin->flags |= SF_OLDDEATH; } if (skin->sprites[0].numframes == 0) @@ -830,7 +830,6 @@ static boolean R_ProcessPatchableFields(skin_t *skin, char *stoken, char *value) // these are uppercase so they can be concatenated with SF_ // 1, true, yes are all valid values GETFLAG(MACHINE) - GETFLAG(NOGIBS) GETFLAG(OLDDEATH) #undef GETFLAG