diff --git a/src/p_local.h b/src/p_local.h index 631920bb6..037e9aa50 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -329,6 +329,7 @@ void P_Attract(mobj_t *source, mobj_t *enemy, boolean nightsgrab); mobj_t *P_GetClosestAxis(mobj_t *source); boolean P_CanRunOnWater(player_t *player, ffloor_t *rover); +boolean P_CheckSolidFFloorSurface(player_t *player, ffloor_t *rover); void P_MaceRotate(mobj_t *center, INT32 baserot, INT32 baseprevrot); diff --git a/src/p_map.c b/src/p_map.c index d0716790b..f78a0b402 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1848,7 +1848,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) continue; } - if (thing->player && P_CheckSolidLava(rover)) + if (thing->player && P_CheckSolidFFloorSurface(thing->player, rover)) ; else if (thing->type == MT_SKIM && (rover->flags & FF_SWIMMABLE)) ; diff --git a/src/p_maputl.c b/src/p_maputl.c index 2e21f5ee3..5acddf09c 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -730,7 +730,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) if (!(rover->flags & FF_EXISTS)) continue; - if (mobj->player && P_CheckSolidLava(rover)) + if (mobj->player && P_CheckSolidFFloorSurface(mobj->player, rover)) ; else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player) || (rover->flags & FF_BLOCKOTHERS && !mobj->player))) @@ -772,7 +772,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) if (!(rover->flags & FF_EXISTS)) continue; - if (mobj->player && P_CheckSolidLava(rover)) + if (mobj->player && P_CheckSolidFFloorSurface(mobj->player, rover)) ; else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player) || (rover->flags & FF_BLOCKOTHERS && !mobj->player))) diff --git a/src/p_mobj.c b/src/p_mobj.c index 96beed530..6853c06f9 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1879,7 +1879,7 @@ void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motype) topheight = P_GetFOFTopZ(mo, sector, rover, mo->x, mo->y, NULL); bottomheight = P_GetFOFBottomZ(mo, sector, rover, mo->x, mo->y, NULL); - if (mo->player && P_CheckSolidLava(rover)) // only the player should stand on lava + if (mo->player && P_CheckSolidFFloorSurface(mo->player, rover)) // only the player should stand on lava or run on water ; else if (motype != 0 && rover->flags & FF_SWIMMABLE) // "scenery" only continue; @@ -2940,6 +2940,34 @@ boolean P_SceneryZMovement(mobj_t *mo) return true; } +// P_CanRunOnWater +// +// Returns true if player can waterrun on the 3D floor +// +boolean P_CanRunOnWater(player_t *player, ffloor_t *rover) +{ + boolean flip = player->mo->eflags & MFE_VERTICALFLIP; + fixed_t topspeed = K_GetKartSpeed(player, false); + fixed_t surfaceheight = flip ? player->mo->waterbottom : player->mo->watertop; + fixed_t playerbottom = flip ? (player->mo->z + player->mo->height) : player->mo->z; + fixed_t clip = flip ? (surfaceheight - playerbottom) : (playerbottom - surfaceheight); + fixed_t span = player->mo->watertop - player->mo->waterbottom; + + return + clip > -(player->mo->height / 2) && + span > player->mo->height && + player->speed / 3 > abs(player->mo->momz) && + (player->speed > 2 * topspeed || (player->speed > + topspeed && K_SlopeResistance(player))) && + (rover->flags & FF_SWIMMABLE); +} + +boolean P_CheckSolidFFloorSurface(player_t *player, ffloor_t *rover) +{ + return P_CheckSolidLava(rover) || + P_CanRunOnWater(player, rover); +} + // // P_MobjCheckWater // @@ -2955,6 +2983,7 @@ void P_MobjCheckWater(mobj_t *mobj) ffloor_t *rover; player_t *p = mobj->player; // Will just be null if not a player. fixed_t height = mobj->height; + fixed_t halfheight = height / 2; boolean wasgroundpounding = false; fixed_t top2 = P_GetSectorCeilingZAt(sector, mobj->x, mobj->y); fixed_t bot2 = P_GetSectorFloorZAt(sector, mobj->x, mobj->y); @@ -2985,14 +3014,14 @@ void P_MobjCheckWater(mobj_t *mobj) if (mobj->eflags & MFE_VERTICALFLIP) { - if (topheight < (thingtop - (height>>1)) - || bottomheight > thingtop) + if (topheight < (thingtop - halfheight) + || bottomheight > (thingtop + halfheight)) continue; } else { - if (topheight < mobj->z - || bottomheight > (mobj->z + (height>>1))) + if (topheight < (mobj->z - halfheight) + || bottomheight > (mobj->z + halfheight)) continue; }