From 20e08562685935b07872cbd1f7b41caf2480a903 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 11 Aug 2023 14:38:24 -0700 Subject: [PATCH] K_SpawnKartMissile: fix Z position at large step up and on top of water FOF - Fix missile teleporting onto the other side of a very large step up. - Such as when firing very close to a wall created by a change in sector floor height. - Or when firing close to a solid midtexture. - Fix missiles teleporting below water FOFs, if fired while the player is water skipping or skiing on top of the FOF. --- src/k_kart.c | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 45a1304e9..c8fe8ba8d 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4762,30 +4762,35 @@ static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t an, I P_SetScale(th, finalscale); th->destscale = finalscale; - if (P_IsObjectOnGround(source)) - { - // floorz and ceilingz aren't properly set to account for FOFs and Polyobjects on spawn - // This should set it for FOFs - P_SetOrigin(th, th->x, th->y, th->z); // however, THIS can fuck up your day. just absolutely ruin you. - if (P_MobjWasRemoved(th)) - return NULL; - - // spawn on the ground if the player is on the ground - if (P_MobjFlip(source) < 0) - { - th->z = th->ceilingz - th->height; - th->eflags |= MFE_VERTICALFLIP; - } - else - th->z = th->floorz; - } - th->angle = an; th->momx = FixedMul(finalspeed, FINECOSINE(an>>ANGLETOFINESHIFT)); th->momy = FixedMul(finalspeed, FINESINE(an>>ANGLETOFINESHIFT)); th->momz = source->momz; + P_CheckPosition(th, x, y, NULL); + + if (P_MobjWasRemoved(th)) + return NULL; + + if ((P_IsObjectFlipped(th) + ? tm.ceilingz - source->ceilingz + : tm.floorz - source->floorz) > P_GetThingStepUp(th, x, y)) + { + // Assuming this is on the boundary of a sector and + // the wall is too tall... I'm not bothering with + // trying to find where the line is. Just nudge this + // object back a bit so it (hopefully) doesn't + // teleport on top of the ledge. + + const fixed_t r = abs(th->radius - source->radius); + + P_SetOrigin(th, source->x - FixedMul(r, FSIN(an)), source->y - FixedMul(r, FCOS(an)), z); + + if (P_MobjWasRemoved(th)) + return NULL; + } + if (source->player != NULL) { th->cusval = source->player->itemscale;