diff --git a/src/k_items.c b/src/k_items.c index b387aa68d..b03a42b66 100644 --- a/src/k_items.c +++ b/src/k_items.c @@ -2523,6 +2523,13 @@ INT16 K_GetShrinkTime(const player_t *player) boolean K_IsAltShrunk(const player_t *player) { + if (!player) + { +#ifdef PARANOIA + CONS_Printf("K_IsAltShrunk: passed NULL player\n"); +#endif + return false; + } return player->growshrinktimer < 0 && K_IsKartItemAlternate(KITEM_SHRINK); } diff --git a/src/k_kart.c b/src/k_kart.c index b0d67bd43..62b43bbf2 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4891,7 +4891,18 @@ void K_DoSneaker(player_t *player, INT32 type) void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound) { - const fixed_t vscale = mapobjectscale + (mo->scale - mapobjectscale); + fixed_t objscale = mo->scale; + + if (mo->player) + { + // For smaller players: fudge the scale calculation by adding a minimum scale. + // In certain cases, the game will pretend they're bigger than they actually are, + // so the game handles springs as such. + // Alt. Shrink *especially* needs this change! + objscale = max(mo->scale, mapobjectscale); + } + + const fixed_t vscale = mapobjectscale + (objscale - mapobjectscale); if (mo->player && mo->player->spectator) return; diff --git a/src/k_terrain.c b/src/k_terrain.c index 96c7f7088..0c3662d63 100644 --- a/src/k_terrain.c +++ b/src/k_terrain.c @@ -763,7 +763,11 @@ void K_ProcessTerrainEffect(mobj_t *mo) // Pogospring panel if (terrain->pogoSpring > 0 && !(mo->eflags & MFE_SPRUNG)) { - const fixed_t hscale = mapobjectscale + (mapobjectscale - player->mo->scale); + // I'm not including the "minimum scale" rant here again. Look at P_DoSpring for that. + // Just know this fixes things with Alt. Shrink. + const fixed_t objscale = max(player->mo->scale, mapobjectscale); + + const fixed_t hscale = mapobjectscale + (mapobjectscale - objscale); fixed_t minspeed = terrain->pogoSpringMin*hscale; fixed_t maxspeed = terrain->pogoSpringMax*hscale; angle_t pushangle = FixedHypot(player->mo->momx, player->mo->momy) ? R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy) : player->mo->angle; diff --git a/src/p_map.c b/src/p_map.c index e15912093..25825ec38 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -46,6 +46,8 @@ #include "k_objects.h" +#include "k_items.h" + tm_t g_tm = {0}; void P_RestoreTMStruct(tm_t tmrestore) @@ -292,8 +294,19 @@ P_DoSpringEx fixed_t horizspeed, angle_t finalAngle) { - const fixed_t hscale = mapobjectscale + (mapobjectscale - object->scale); - const fixed_t vscale = mapobjectscale + (object->scale - mapobjectscale); + fixed_t objscale = object->scale; + + if (object->player) + { + // For smaller players: fudge the scale calculation by adding a minimum scale. + // In certain cases, the game will pretend they're bigger than they actually are, + // so the game handles springs as such. + // Alt. Shrink *especially* needs this change! + objscale = max(object->scale, mapobjectscale); + } + + const fixed_t hscale = mapobjectscale + (mapobjectscale - objscale); + const fixed_t vscale = mapobjectscale + (objscale - mapobjectscale); object->standingslope = NULL; // Okay, now we know it's not going to be relevant - no launching off at silly angles for you. object->terrain = NULL; @@ -335,8 +348,19 @@ P_DoSpringEx // boolean P_DoSpring(mobj_t *spring, mobj_t *object) { - const fixed_t hscale = mapobjectscale + (mapobjectscale - object->scale); - const fixed_t vscale = mapobjectscale + (object->scale - mapobjectscale); + fixed_t objscale = object->scale; + + if (object->player) + { + // For smaller players: fudge the scale calculation by adding a minimum scale. + // In certain cases, the game will pretend they're bigger than they actually are, + // so the game handles springs as such. + // Alt. Shrink *especially* needs this change! + objscale = max(object->scale, mapobjectscale); + } + + const fixed_t hscale = mapobjectscale + (mapobjectscale - objscale); + const fixed_t vscale = mapobjectscale + (objscale - mapobjectscale); fixed_t offx, offy; fixed_t vertispeed = spring->info->mass; fixed_t horizspeed = spring->info->damage; @@ -523,6 +547,7 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object) static BlockItReturn_t PIT_CheckThing(mobj_t *thing) { fixed_t blockdist; + boolean shrinkleeway = false; if (g_tm.thing == NULL || P_MobjWasRemoved(g_tm.thing) == true) return BMIT_STOP; // func just popped our g_tm.thing, cannot continue. @@ -553,6 +578,35 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing) blockdist = thing->radius + g_tm.thing->radius; + if (thing->flags & MF_SPRING) + { + // Testing a spring object; check if the other object: + // * Has a player + // * Is smaller than usual + // If this is true, fudge collisions for this interaction. + if (g_tm.thing->player && (g_tm.thing->scale < mapobjectscale)) + { + const fixed_t radiusrescale = FixedDiv(mapobjectscale, g_tm.thing->scale); + + blockdist = thing->radius + FixedMul(g_tm.thing->radius, radiusrescale); + shrinkleeway = true; + } + } + else if (g_tm.thing->flags & MF_SPRING) + { + // Testing a spring object; check if the other object: + // * Has a player + // * Is smaller than usual + // If this is true, fudge collisions for this interaction. + if (thing->player && (thing->scale < mapobjectscale)) + { + const fixed_t radiusrescale = FixedDiv(mapobjectscale, thing->scale); + + blockdist = FixedMul(thing->radius, radiusrescale) + g_tm.thing->radius; + shrinkleeway = true; + } + } + if (abs(thing->x - g_tm.x) >= blockdist || abs(thing->y - g_tm.y) >= blockdist) return BMIT_CONTINUE; // didn't hit it @@ -1243,7 +1297,20 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing) P_DoFanAndGasJet(thing, g_tm.thing); else if (thing->flags & MF_SPRING) { - if ( thing->z <= g_tm.thing->z + g_tm.thing->height + fixed_t tm_thing_height = 0; + + if (shrinkleeway) + { + const fixed_t radiusrescale = FixedDiv(mapobjectscale, g_tm.thing->scale); + + tm_thing_height = FixedMul(g_tm.thing->height, radiusrescale); + } + else + { + tm_thing_height = g_tm.thing->height; + } + + if ( thing->z <= g_tm.thing->z + tm_thing_height && g_tm.thing->z <= thing->z + thing->height) if (P_DoSpring(thing, g_tm.thing)) return BMIT_ABORT; diff --git a/src/p_spec.c b/src/p_spec.c index 39fd9b935..241dacd18 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -5197,7 +5197,8 @@ static void P_ProcessPogoSpring(player_t *player, boolean isTouching, int type) return; } - const fixed_t hscale = mapobjectscale + (mapobjectscale - player->mo->scale); + const fixed_t playerscale = max(mapobjectscale, player->mo->scale); + const fixed_t hscale = mapobjectscale + (mapobjectscale - playerscale); const fixed_t minspeed = 24*hscale; const fixed_t maxspeed = 28*hscale; angle_t pushangle = FixedHypot(player->mo->momx, player->mo->momy) ? R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy) : player->mo->angle;