diff --git a/source/build/src/clip.cpp b/source/build/src/clip.cpp
index 5f3ffdbec..53579f681 100644
--- a/source/build/src/clip.cpp
+++ b/source/build/src/clip.cpp
@@ -608,40 +608,7 @@ CollisionBase clipmove_(vec3_t * const pos, int * const sectnum, int32_t xvect,
                 return clipReturn;
             }
 
-        double tempint2, tempint1 = INT32_MAX;
-        *sectnum = -1;
-        for (int j = (int)sector.Size() - 1; j >= 0; j--)
-        {
-            auto sect = &sector[j];
-            if (inside(fpos.X, fpos.Y, sect) == 1)
-            {
-                tempint2 = getceilzofslopeptr(sect, fpos.X, fpos.Y) - fpos.Z;
-
-                if (tempint2 > 0)
-                {
-                    if (tempint2 < tempint1)
-                    {
-                        *sectnum = j;
-                        tempint1 = tempint2;
-                    }
-                }
-                else
-                {
-                    tempint2 = fpos.Z - getflorzofslopeptr(sect, fpos.X, fpos.Y);
-
-                    if (tempint2 <= 0)
-                    {
-                        *sectnum = j;
-                        return clipReturn;
-                    }
-                    if (tempint2 < tempint1)
-                    {
-                        *sectnum = j;
-                        tempint1 = tempint2;
-                    }
-                }
-            }
-        }
+        *sectnum = FindBestSector(fpos);
     }
 
     return clipReturn;
diff --git a/source/core/gamefuncs.cpp b/source/core/gamefuncs.cpp
index 13710fe18..5abd9d2a7 100644
--- a/source/core/gamefuncs.cpp
+++ b/source/core/gamefuncs.cpp
@@ -1261,6 +1261,54 @@ int pushmove(DVector3& pos, sectortype** pSect, double walldist, double ceildist
 //
 //==========================================================================
 
+int FindBestSector(const DVector3& pos)
+{
+	int bestnum = 1;
+	double bestdist = FLT_MAX;
+	for (int secnum = (int)sector.Size() - 1; secnum >= 0; secnum--)
+	{
+		auto sect = &sector[secnum];
+		if (inside(pos.X, pos.Y, sect))
+		{
+			double ceilz, floorz;
+			calcSlope(sect, pos.X, pos.Y, &ceilz, &floorz);
+
+			if (pos.Z < ceilz)
+			{
+				// above ceiling
+				double dist = ceilz - pos.Z;
+				if (dist < bestdist)
+				{
+					bestnum = secnum;
+					bestdist = dist;
+				}
+			}
+			else if (pos.Z > floorz)
+			{
+				// below floor
+				double dist = pos.Z - floorz;
+				if (dist < bestdist)
+				{
+					bestnum = secnum;
+					bestdist = dist;
+				}
+			}
+			else
+			{
+				// inside sector
+				return secnum;
+			}
+		}
+	}
+	return bestnum;
+}
+
+//==========================================================================
+//
+//
+//
+//==========================================================================
+
 bool isAwayFromWall(DCoreActor* ac, double delta)
 {
 	sectortype* s1;
diff --git a/source/core/gamefuncs.h b/source/core/gamefuncs.h
index 85ef4a4b1..9ae337068 100644
--- a/source/core/gamefuncs.h
+++ b/source/core/gamefuncs.h
@@ -271,6 +271,11 @@ tspritetype* renderAddTsprite(tspriteArray& tsprites, DCoreActor* actor);
 
 
 
+int FindBestSector(const DVector3& pos);
+
+
+tspritetype* renderAddTsprite(tspriteArray& tsprites, DCoreActor* actor);
+
 void setWallSectors();
 void GetWallSpritePosition(const spritetypebase* spr, const DVector2& pos, DVector2* out, bool render = false);
 void GetFlatSpritePosition(DCoreActor* spr, const DVector2& pos, DVector2* out, double* outz = nullptr, bool render = false);