diff --git a/src/lua_baselib.c b/src/lua_baselib.c index d74af4214..e753c5af3 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -1730,6 +1730,18 @@ static int lib_pFloorzAtPos(lua_State *L) return 1; } +static int lib_pCeilingzAtPos(lua_State *L) +{ + fixed_t x = luaL_checkfixed(L, 1); + fixed_t y = luaL_checkfixed(L, 2); + fixed_t z = luaL_checkfixed(L, 3); + fixed_t height = luaL_checkfixed(L, 4); + //HUDSAFE + INLEVEL + lua_pushfixed(L, P_CeilingzAtPos(x, y, z, height)); + return 1; +} + static int lib_pDoSpring(lua_State *L) { mobj_t *spring = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); @@ -3604,6 +3616,7 @@ static luaL_Reg lib[] = { {"P_CheckHoopPosition",lib_pCheckHoopPosition}, {"P_RadiusAttack",lib_pRadiusAttack}, {"P_FloorzAtPos",lib_pFloorzAtPos}, + {"P_CeilingzAtPos",lib_pCeilingzAtPos}, {"P_DoSpring",lib_pDoSpring}, // p_inter diff --git a/src/p_local.h b/src/p_local.h index cf3a66e9d..8a5084962 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -428,6 +428,7 @@ void P_Initsecnode(void); void P_RadiusAttack(mobj_t *spot, mobj_t *source, fixed_t damagedist, UINT8 damagetype, boolean sightcheck); fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height); +fixed_t P_CeilingzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height); boolean PIT_PushableMoved(mobj_t *thing); boolean P_DoSpring(mobj_t *spring, mobj_t *object); diff --git a/src/p_map.c b/src/p_map.c index 74c2790f7..cb06f7d77 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -4963,7 +4963,7 @@ void P_MapEnd(void) } // P_FloorzAtPos -// Returns the floorz of the XYZ position // TODO: Need ceilingpos function too +// Returns the floorz of the XYZ position // Tails 05-26-2003 fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height) { @@ -5007,3 +5007,47 @@ fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height) return floorz; } + +// P_CeilingZAtPos +// Returns the ceilingz of the XYZ position +fixed_t P_CeilingzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height) +{ + sector_t *sec = R_PointInSubsector(x, y)->sector; + fixed_t ceilingz = P_GetSectorCeilingZAt(sec, x, y); + + if (sec->ffloors) + { + ffloor_t *rover; + fixed_t delta1, delta2, thingtop = z + height; + + for (rover = sec->ffloors; rover; rover = rover->next) + { + fixed_t topheight, bottomheight; + if (!(rover->flags & FF_EXISTS)) + continue; + + if ((!(rover->flags & FF_SOLID || rover->flags & FF_QUICKSAND) || (rover->flags & FF_SWIMMABLE))) + continue; + + topheight = P_GetFFloorTopZAt (rover, x, y); + bottomheight = P_GetFFloorBottomZAt(rover, x, y); + + if (rover->flags & FF_QUICKSAND) + { + if (thingtop > bottomheight && topheight > z) + { + if (ceilingz > z) + ceilingz = z; + } + continue; + } + + delta1 = z - (bottomheight + ((topheight - bottomheight)/2)); + delta2 = thingtop - (bottomheight + ((topheight - bottomheight)/2)); + if (bottomheight < ceilingz && abs(delta1) > abs(delta2)) + ceilingz = bottomheight; + } + } + + return ceilingz; +} \ No newline at end of file