changeset 723:256211e8243a

ODM_GetFloorLevel & BLV_GetFloorLevel
author Ritor1
date Thu, 21 Mar 2013 16:09:44 +0600
parents 70c5a87a1307
children 737d7fec67f0
files Actor.cpp Indoor.cpp Outdoor.cpp SpriteObject.cpp mm7_2.cpp mm7_3.cpp mm7_4.cpp mm7_data.cpp mm7_data.h
diffstat 9 files changed, 252 insertions(+), 429 deletions(-) [+]
line wrap: on
line diff
--- a/Actor.cpp	Wed Mar 20 17:49:15 2013 +0600
+++ b/Actor.cpp	Thu Mar 21 16:09:44 2013 +0600
@@ -4083,7 +4083,7 @@
         v27 = v30->vPosition.z,
         result = pIndoor->GetSector(v15, v17, v21),
         result == v28)
-    && (result = _46CEC3_get_floor_level(v15, v17, v27, result, &uFaceID), result != -30000)
+    && (result = BLV_GetFloorLevel(v15, v17, v27, result, &uFaceID), result != -30000)
     && (result = abs(result - v27), result <= 1024) )
   {
     v23 = v30;
--- a/Indoor.cpp	Wed Mar 20 17:49:15 2013 +0600
+++ b/Indoor.cpp	Thu Mar 21 16:09:44 2013 +0600
@@ -3977,7 +3977,7 @@
         v5 = pIndoor->GetSector(v0->vPosition.x, v0->vPosition.y, v4);
         v0->uSectorID = v5;
         if ( !v5
-          || (v56 = _46CEC3_get_floor_level(v0->vPosition.x, v0->vPosition.y, v0->vPosition.z, v5, &uFaceID), v56 == -30000) )
+          || (v56 = BLV_GetFloorLevel(v0->vPosition.x, v0->vPosition.y, v0->vPosition.z, v5, &uFaceID), v56 == -30000) )
           goto LABEL_123;
       }
       if ( v0->uCurrentActionAnimation == ANIM_Walking)
--- a/Outdoor.cpp	Wed Mar 20 17:49:15 2013 +0600
+++ b/Outdoor.cpp	Thu Mar 21 16:09:44 2013 +0600
@@ -516,7 +516,7 @@
   if ( pParty->uFlags & 8
     || (v15 = 0,
         v16 = 0,
-        sub_46D49E_prolly_get_world_y_under_party(x, y, z, pParty->uDefaultPartyHeight, &v15, &v16, 0),
+        ODM_GetFloorLevel(x, y, z, pParty->uDefaultPartyHeight, &v15, &v16, 0),
         v16)
     || v15 )
     return 2;
--- a/SpriteObject.cpp	Wed Mar 20 17:49:15 2013 +0600
+++ b/SpriteObject.cpp	Thu Mar 21 16:09:44 2013 +0600
@@ -240,7 +240,7 @@
   v4 = v1->vPosition.x;
   v5 = v2->uHeight;
   v55 = 0;
-  v6 = sub_46D49E_prolly_get_world_y_under_party(v4, v3, v1->vPosition.z, v5, &v59, &v55, 0);
+  v6 = ODM_GetFloorLevel(v4, v3, v1->vPosition.z, v5, &v59, &v55, 0);
   v7 = v6;
   v54 = v6;
   v8 = v6 + 1;
@@ -428,7 +428,7 @@
           _46DF1A_collide_against_actor(i, 0);
       }
       v26 = stru_721530.normal2.z - stru_721530.prolly_normal_d - 1;
-      v27 = sub_46D49E_prolly_get_world_y_under_party(
+      v27 = ODM_GetFloorLevel(
               stru_721530.normal2.x,
               stru_721530.normal2.y,
               stru_721530.normal2.z - stru_721530.prolly_normal_d - 1,
@@ -644,7 +644,7 @@
   //v3 = pSpriteObject->vPosition.x;
   //v37 = &pObjectList->pObjects[pSpriteObject->uObjectDescID];
   pSpriteObject->uSectorID = pIndoor->GetSector(pSpriteObject->vPosition.x, pSpriteObject->vPosition.y, pSpriteObject->vPosition.z);
-  v42 = _46CEC3_get_floor_level(pSpriteObject->vPosition.x, pSpriteObject->vPosition.y, pSpriteObject->vPosition.z, pSpriteObject->uSectorID, &uFaceID);
+  v42 = BLV_GetFloorLevel(pSpriteObject->vPosition.x, pSpriteObject->vPosition.y, pSpriteObject->vPosition.z, pSpriteObject->uSectorID, &uFaceID);
   if ( abs(pSpriteObject->vPosition.x) > 32767
     || abs(pSpriteObject->vPosition.y) > 32767
     || abs(pSpriteObject->vPosition.z) > 20000
--- a/mm7_2.cpp	Wed Mar 20 17:49:15 2013 +0600
+++ b/mm7_2.cpp	Thu Mar 21 16:09:44 2013 +0600
@@ -5106,7 +5106,7 @@
       v37 = pIndoor->GetSector(pPosX, a4, v36);
       if ( v37 == pSector )
       {
-        v38 = _46CEC3_get_floor_level(pPosX, a4, a3, v37, &uFaceID);
+        v38 = BLV_GetFloorLevel(pPosX, a4, a3, v37, &uFaceID);
         v39 = v38;
         if ( v38 != -30000 )
         {
@@ -5237,7 +5237,7 @@
       || (v22 = pParty->vPosition.z,
           result = pIndoor->GetSector(v11, v14, pParty->vPosition.z),
           result == v21)
-      && (result = _46CEC3_get_floor_level(v11, v14, v22, result, &uFaceID), result != -30000)
+      && (result = BLV_GetFloorLevel(v11, v14, v22, result, &uFaceID), result != -30000)
       && (result = abs(result - v22), result <= 1024) )
     {
       if ( v20 == uNumActors )
@@ -5549,7 +5549,7 @@
       v19.vPosition.z = pParty->vPosition.z;
       v26 = 0;
       v27 = 0;
-      v19.vPosition.z = sub_46D49E_prolly_get_world_y_under_party(
+      v19.vPosition.z = ODM_GetFloorLevel(
                           v19.vPosition.x,
                           v23 + pParty->vPosition.y,
                           pParty->vPosition.z,
@@ -5607,7 +5607,7 @@
       v17 = pIndoor->GetSector(v19.vPosition.x, v23 + pParty->vPosition.y, pParty->vPosition.z);
       if ( v17 == v22 )
       {
-        v18 = _46CEC3_get_floor_level(v19.vPosition.x, v19.vPosition.y, v19.vPosition.z, v17, &uFaceID);
+        v18 = BLV_GetFloorLevel(v19.vPosition.x, v19.vPosition.y, v19.vPosition.z, v17, &uFaceID);
         v19.vPosition.z = v18;
         if ( v18 != -30000 )
         {
--- a/mm7_3.cpp	Wed Mar 20 17:49:15 2013 +0600
+++ b/mm7_3.cpp	Thu Mar 21 16:09:44 2013 +0600
@@ -498,7 +498,7 @@
 int _46ED1B_collide_against_floor(int x, int y, int z, unsigned int *pSectorID, unsigned int *pFaceID)
 {
   uint uFaceID = -1;
-  int floor_level = _46CEC3_get_floor_level(x, y, z, *pSectorID, &uFaceID);
+  int floor_level = BLV_GetFloorLevel(x, y, z, *pSectorID, &uFaceID);
 
   if (floor_level != -30000 && floor_level <= z + 50)
   {
@@ -509,7 +509,7 @@
   uint uSectorID = pIndoor->GetSector(x, y, z);
   *pSectorID = uSectorID;
 
-  floor_level = _46CEC3_get_floor_level(x, y, z, uSectorID, &uFaceID);
+  floor_level = BLV_GetFloorLevel(x, y, z, uSectorID, &uFaceID);
   if (uSectorID && floor_level != -30000)
     *pFaceID = uFaceID;
   else return -30000;
@@ -971,7 +971,7 @@
     if ( !v0->CanAct() )
       v74 = 0;
     v70 = IsTerrainSlopeTooHigh(v0->vPosition.x, v0->vPosition.y);
-    v5 = sub_46D49E_prolly_get_world_y_under_party(
+    v5 = ODM_GetFloorLevel(
            v0->vPosition.x,
            v0->vPosition.y,
            v0->vPosition.z,
@@ -1148,7 +1148,7 @@
         v70 = (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.z) >> 16;
       v34 = 0;
       v35 = stru_721530.normal2.z - stru_721530.prolly_normal_d - 1;
-      v36 = sub_46D49E_prolly_get_world_y_under_party(
+      v36 = ODM_GetFloorLevel(
               stru_721530.normal2.x,
               stru_721530.normal2.y,
               stru_721530.normal2.z - stru_721530.prolly_normal_d - 1,
@@ -2288,14 +2288,14 @@
   int v113; // [sp+4Ch] [bp-48h]@1
   unsigned int v114; // [sp+50h] [bp-44h]@1
   int _walk_speed; // [sp+54h] [bp-40h]@48
-  int v116; // [sp+58h] [bp-3Ch]@1
-  int v117; // [sp+5Ch] [bp-38h]@1
+  int pX; // [sp+58h] [bp-3Ch]@1
+  int pY; // [sp+5Ch] [bp-38h]@1
   int v118; // [sp+60h] [bp-34h]@1
   //Player **v119; // [sp+64h] [bp-30h]@4
   int _angle_x; // [sp+68h] [bp-2Ch]@48
   int v121; // [sp+6Ch] [bp-28h]@1
   unsigned int v122; // [sp+70h] [bp-24h]@180
-  int v123; // [sp+74h] [bp-20h]@1
+  int pZ; // [sp+74h] [bp-20h]@1
   int v124; // [sp+78h] [bp-1Ch]@1
   int _angle_y; // [sp+7Ch] [bp-18h]@48
   int v126; // [sp+80h] [bp-14h]@48
@@ -2305,13 +2305,13 @@
   int v130; // [sp+90h] [bp-4h]@14
 
   v121 = pParty->uFallSpeed;
-  v123 = pParty->vPosition.z;
+  pZ = pParty->vPosition.z;
   v1 = 0;
   v103 = 0;
   v2 = 0;
   *(float *)&v128 = 0.0;
-  v116 = pParty->vPosition.x;
-  v117 = pParty->vPosition.y;
+  pX = pParty->vPosition.x;
+  pY = pParty->vPosition.y;
   v113 = pParty->field_6F0;
   bJumping = 0;
   auto partyAtHighSlope = IsTerrainSlopeTooHigh(pParty->vPosition.x, pParty->vPosition.y);
@@ -2353,13 +2353,13 @@
 		//*(int *)&pParty->pArtifactsFound[6972 * pParty->pPartyBuffs[18].uCaster + 10] <= 0 )
       bWaterWalk = 0;
   }
-  v3 = sub_46D49E_prolly_get_world_y_under_party(v116, v117, v123, pParty->uPartyHeight, &v130, &v108, bWaterWalk);
+  v3 = ODM_GetFloorLevel(pX, pY, pZ, pParty->uPartyHeight, &v130, &v108, bWaterWalk);
   v111 = v3;
   if ( bFeatherFall )
     pParty->uFallStartY = v3;
   else
     v3 = pParty->uFallStartY;
-  if ( v3 - v123 > 512 && !bFeatherFall && v123 <= v111 + 1 )
+  if ( v3 - pZ > 512 && !bFeatherFall && pZ <= v111 + 1 )
   {
     if (pParty->uFlags & PARTY_FLAGS_1_LANDING)
     {
@@ -2372,7 +2372,7 @@
       if ( !player->HasEnchantedItemEquipped(72) && !player->WearsItem(529, 8) )
       {
         player->ReceiveDamage(
-            (signed int)((pParty->uFallStartY - v123) * (unsigned __int64)(player->GetMaxHealth() / 10)) / 256,
+            (signed int)((pParty->uFallStartY - pZ) * (unsigned __int64)(player->GetMaxHealth() / 10)) / 256,
             4);
         v105 = 20 - player->_48EA1B_get_static_effect(player->GetActualEndurance());
         player->SetRecoveryTime((signed __int64)((double)v105 * flt_6BE3A4_debug_recmod1 * 2.133333333333333));
@@ -2383,10 +2383,10 @@
   }
   v109 = -1;
   if ( pParty->bFlying )
-    v109 = sub_46D8E3(v116, v117, v123 + pParty->uPartyHeight, (int)&v102);
+    v109 = sub_46D8E3(pX, pY, pZ + pParty->uPartyHeight, (int)&v102);
   v107 = v108 == 0;
   v105 = v111 + 1;
-  if ( v123 <= v111 + 1 )
+  if ( pZ <= v111 + 1 )
   {
     v109 = -1;
     pParty->bFlying = false;
@@ -2395,7 +2395,7 @@
   {
     bJumping = 1;
   }
-  v101 = v123 - v111 <= 32;
+  v101 = pZ - v111 <= 32;
   if ( bWalkSound && pParty->field_6F8 > 0 )
     pParty->field_6F8 -= pEventTimer->uTimeElapsed;
   if (!bUnderwater
@@ -2452,28 +2452,28 @@
           {
             if ( pParty->vPosition.z < 4000 || bJumping )
             {
-              v123 += 30;
+              pZ += 30;
               v113 += 30;
               pParty->bFlying = 1;
-              if ( v123 > 4000 )
+              if ( pZ > 4000 )
               {
-                v123 = 4000;
+                pZ = 4000;
                 v113 = 4000;
               }
               v1 = 0;
               v2 = 0;
               v121 = 0;
               *(float *)&v128 = 0.0;
-              if ( v102 && v123 < v109 && (signed int)(pParty->uPartyHeight + v123) >= v109 )
+              if ( v102 && pZ < v109 && (signed int)(pParty->uPartyHeight + pZ) >= v109 )
               {
                 pParty->field_6E0 = 0;
                 pParty->field_6E4 = 0;
                 pPartyActionQueue->uNumActions = 0;
                 pParty->uFlags |= PARTY_FLAGS_1_LANDING;
                 pParty->vPosition.z = v109 - pParty->uPartyHeight - 31;
-                pParty->field_6F0 = v123;
+                pParty->field_6F0 = pZ;
                 pParty->bFlying = 0;
-                v123 = v109 - pParty->uPartyHeight - 31;
+                pZ = v109 - pParty->uPartyHeight - 31;
                 v113 = pParty->field_6F0;
               }
               pParty->uFallSpeed = 0;
@@ -2491,13 +2491,13 @@
             || pParty->pPartyBuffs[7].uFlags & 1
             || pParty->pPlayers[pParty->pPartyBuffs[7].uCaster - 1].sMana > 0 )//*(int *)&pParty->pArtifactsFound[6972 * pParty->pPartyBuffs[7].uCaster + 10] > 0 )
           {
-            v123 -= 30;
+            pZ -= 30;
             v113 -= 30;
             pParty->uFallSpeed = 0;
             v121 = 0;
             pParty->bFlying = 1;
             v127 = (BSPModel *)1;
-            if ( v123 <= v111 )
+            if ( pZ <= v111 )
             {
               pParty->bFlying = 0;
               pPartyActionQueue->uNumActions = 0;
@@ -2723,7 +2723,7 @@
 LABEL_123:
   pParty->sRotationY = _angle_y;
   pParty->sRotationX = _angle_x;
-  if ( v123 < v111 )
+  if ( pZ < v111 )
   {
     if ( pParty->bFlying )
     {
@@ -2731,23 +2731,23 @@
       v31 = GetTickCount();
       v126 = stru_5C6E00->Cos(v31);
       v129 = (unsigned __int64)(4i64 * v126) >> 16;
-      v123 = v113 + v129;
+      pZ = v113 + v129;
       if ( v127 )
-        v123 = v113;
+        pZ = v113;
       if (pParty->FlyActive())
         stru_5E4C90._decor_events[20 * pParty->pPartyBuffs[7].uOverlayID + 119] &= 0xFEu;
-      pParty->uFallStartY = v123;
+      pParty->uFallStartY = pZ;
       goto LABEL_141;
     }
     if ( v130 && v121 )
-      sub_42F960_create_object(v116, v117, v111);
+      sub_42F960_create_object(pX, pY, v111);
     v121 = 0;
-    v123 = v111;
+    pZ = v111;
     pParty->uFallStartY = v111;
   }
   if ( pParty->bFlying )
     goto LABEL_130;
-  v113 = v123;
+  v113 = pZ;
   if (pParty->FlyActive())
     stru_5E4C90._decor_events[20 * pParty->pPartyBuffs[7].uOverlayID + 119] |= 1u;
 
@@ -2774,8 +2774,8 @@
     // rolling down the hill
     // how it's done: you get a little bit pushed in the air along terrain normal, getting in the air
     // and falling to the gravity, gradually sliding downwards. nice trick
-    v123 = v111;
-    ODM_GetTerrainNormalAt(v116, v117, &v98);
+    pZ = v111;
+    ODM_GetTerrainNormalAt(pX, pY, &v98);
     v35 = v121 + -8 * pEventTimer->uTimeElapsed * GetGravityStrength();
     v129 = abs((signed __int64)v2 * v98.x + (signed __int64)v1 * v98.y + (signed __int64)v35 * v98.z) >> 16;
     v2 += (unsigned __int64)(v129 * (signed __int64)v98.x) >> 16;
@@ -2808,7 +2808,7 @@
   else
   {
 LABEL_150:
-  pParty->uFallStartY = v123;
+  pParty->uFallStartY = pZ;
   }
 
   if ( v2 * v2 + v1 * v1 < 400 && !partyAtHighSlope )
@@ -2825,13 +2825,13 @@
   stru_721530.field_C = pParty->uPartyHeight - 32;
   do
   {
-    stru_721530.field_34.x = v116;
-    stru_721530.normal.x = v116;
+    stru_721530.field_34.x = pX;
+    stru_721530.normal.x = pX;
     stru_721530.field_1C = v2;
-    stru_721530.field_34.y = v117;
-    stru_721530.normal.y = v117;
-    stru_721530.normal.z = stru_721530.prolly_normal_d + v123 + 1;
-    stru_721530.field_34.z = stru_721530.field_C + v123 + 1;
+    stru_721530.field_34.y = pY;
+    stru_721530.normal.y = pY;
+    stru_721530.normal.z = stru_721530.prolly_normal_d + pZ + 1;
+    stru_721530.field_34.z = stru_721530.field_C + pZ + 1;
     stru_721530.field_20 = v128;
     stru_721530.field_24 = v121;
     v36 = 0;
@@ -2855,24 +2855,17 @@
     }
     else
     {
-      _angle_x = v116 + ((unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.x) >> 16);
-      _angle_y = v117 + ((unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.y) >> 16);
+      _angle_x = pX + ((unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.x) >> 16);
+      _angle_y = pY + ((unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.y) >> 16);
       v127 = (BSPModel *)((unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.z) >> 16);
-      v40 = ((unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.z) >> 16) + v123;
+      v40 = ((unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.z) >> 16) + pZ;
     }
     v122 = v40;
-    sub_46D49E_prolly_get_world_y_under_party(_angle_x, _angle_y, v40, pParty->uPartyHeight, &v130, &v108, 0);
-    v129 = sub_46D49E_prolly_get_world_y_under_party(_angle_x, v117, v40, pParty->uPartyHeight, &v130, &v97, 0);
-    auto v119 = sub_46D49E_prolly_get_world_y_under_party(
-                        v116,
-                        _angle_y,
-                        v40,
-                        pParty->uPartyHeight,
-                        &v130,
-                        &v110,
-                        0);
-    v127 = (BSPModel *)IsTerrainSlopeTooHigh(_angle_x, v117);
-    v42 = IsTerrainSlopeTooHigh(v116, _angle_y);
+    ODM_GetFloorLevel(_angle_x, _angle_y, v40, pParty->uPartyHeight, &v130, &v108, 0);
+    v129 = ODM_GetFloorLevel(_angle_x, pY, v40, pParty->uPartyHeight, &v130, &v97, 0);
+    auto v119 = ODM_GetFloorLevel(pX, _angle_y, v40, pParty->uPartyHeight, &v130, &v110, 0);
+    v127 = (BSPModel *)IsTerrainSlopeTooHigh(_angle_x, pY);
+    v42 = IsTerrainSlopeTooHigh(pX, _angle_y);
     v107 = 0;
     v118 = v42;
     if ( !v97 && !v110 && !v108 )
@@ -2881,48 +2874,41 @@
     v44 = 1;
     if ( bUnderwater || !v107 )
       goto LABEL_197;
-    if ( v127 && v129 > v123 )
+    if ( v127 && v129 > pZ )
       v44 = 0;
-    if ( v118 && v119 > v123 )
+    if ( v118 && v119 > pZ )
       v43 = 0;
     if ( v44 )
       goto LABEL_197;
     if ( v43 )
       goto LABEL_198;
-    v127 = (BSPModel *)sub_46D49E_prolly_get_world_y_under_party(
-                         _angle_x,
-                         _angle_y,
-                         v40,
-                         pParty->uPartyHeight,
-                         &v130,
-                         &v108,
-                         0);
-    if ( IsTerrainSlopeTooHigh(_angle_x, _angle_y) && (signed int)v127 <= v123 )
+    v127 = (BSPModel *)ODM_GetFloorLevel(_angle_x, _angle_y, v40, pParty->uPartyHeight, &v130, &v108, 0);
+    if ( IsTerrainSlopeTooHigh(_angle_x, _angle_y) && (signed int)v127 <= pZ )
     {
       v43 = 1;
 LABEL_197:
-      v116 = _angle_x;
+      pX = _angle_x;
       if ( !v43 )
         goto LABEL_199;
 LABEL_198:
-      v117 = _angle_y;
+      pY = _angle_y;
     }
 LABEL_199:
     if ( stru_721530.field_7C >= stru_721530.field_6C )
     {
       if ( !v107 )
       {
-        v116 = stru_721530.normal2.x;
-        v117 = stru_721530.normal2.y;
-      }
-      v123 = stru_721530.normal2.z - stru_721530.prolly_normal_d - 1;
+        pX = stru_721530.normal2.x;
+        pY = stru_721530.normal2.y;
+      }
+      pZ = stru_721530.normal2.z - stru_721530.prolly_normal_d - 1;
       break;
     }
     stru_721530.field_70 += stru_721530.field_7C;
-    v116 = _angle_x;
-    v117 = _angle_y;
+    pX = _angle_x;
+    pY = _angle_y;
     v45 = stru_721530.uFaceID;
-    v123 = v40;
+    pZ = v40;
     if ( (stru_721530.uFaceID & 7) == OBJECT_Actor)
     {
       if (pParty->Invisible())
@@ -2972,7 +2958,7 @@
         {
           if ( v121 < 0 )
             v121 = 0;
-          v123 = v127->pVertices.pVertices[v47->pVertexIDs[0]].z + 1;
+          pZ = v127->pVertices.pVertices[v47->pVertexIDs[0]].z + 1;
           if ( v2 * v2 + v128 * v128 < 400 )
           {
             v2 = 0;
@@ -3006,10 +2992,10 @@
                             + _angle_x * v47->pFacePlane.vNormal.x) >> 16);
           if ( v55 > 0 )
           {
-            v116 = _angle_x + (v47->pFacePlane.vNormal.x * v55 >> 16);
-            v117 = _angle_y + (v47->pFacePlane.vNormal.y * v55 >> 16);
+            pX = _angle_x + (v47->pFacePlane.vNormal.x * v55 >> 16);
+            pY = _angle_y + (v47->pFacePlane.vNormal.y * v55 >> 16);
             if ( !v119 )
-              v123 = v122 + (v47->pFacePlane.vNormal.z * v55 >> 16);
+              pZ = v122 + (v47->pFacePlane.vNormal.z * v55 >> 16);
           }
 LABEL_220:
           v45 = stru_721530.uFaceID;
@@ -3051,9 +3037,9 @@
   while ( v126 < 100 );
   if ( bWalkSound && pParty->field_6F8 <= 0 )
   {
-    v122 = abs(pParty->vPosition.x - v116);
-    v126 = abs(pParty->vPosition.y - v117);
-    v62 = abs(pParty->vPosition.z - v123);
+    v122 = abs(pParty->vPosition.x - pX);
+    v126 = abs(pParty->vPosition.y - pY);
+    v62 = abs(pParty->vPosition.z - pZ);
     if ( integer_sqrt(v122 * v122 + v126 * v126 + v62 * v62) < 8 )
       goto LABEL_344;
     if ( v114 && (!bJumping || v101) )
@@ -3124,8 +3110,8 @@
     pParty->uFlags |= PARTY_FLAGS_1_FALLING;
   v126 = WorldPosToGridCellX(pParty->vPosition.x);
   v65 = WorldPosToGridCellZ(pParty->vPosition.y) - 1;
-  v114 = WorldPosToGridCellX(v116);
-  v66 = WorldPosToGridCellZ(v117) - 1;
+  v114 = WorldPosToGridCellX(pX);
+  v66 = WorldPosToGridCellZ(pY) - 1;
   v127 = (BSPModel *)(((unsigned int)~pOutdoor->ActuallyGetSomeOtherTileInfo(v126, v65) >> 1) & 1);
   v122 = ((unsigned int)~pOutdoor->ActuallyGetSomeOtherTileInfo(v114, v65) >> 1) & 1;
   v67 = pOutdoor->ActuallyGetSomeOtherTileInfo(v126, v66);
@@ -3137,16 +3123,16 @@
     v68 = 1;
   if ( v68 )
   {
-    v70 = v123;
-    v71 = v116;
-    v72 = v117;
+    v70 = pZ;
+    v71 = pX;
+    v72 = pY;
     pParty->uFallSpeed = v121;
-    v73 = v123;
-    pParty->vPosition.x = v116;
-    pParty->vPosition.y = v117;
-    pParty->vPosition.z = v123;
+    v73 = pZ;
+    pParty->vPosition.x = pX;
+    pParty->vPosition.y = pY;
+    pParty->vPosition.z = pZ;
     pParty->field_6F0 = v113;
-    if ( v123 > 8160 )
+    if ( pZ > 8160 )
     {
       v73 = 8160;
       pParty->uFallStartY = 8160;
@@ -3220,7 +3206,7 @@
 LABEL_306:
   if ( v77 )
   {
-    pParty->vPosition.x = v116;
+    pParty->vPosition.x = pX;
     if ( !v78 )
       goto LABEL_313;
     goto LABEL_312;
@@ -3228,7 +3214,7 @@
   if ( v78 )
   {
 LABEL_312:
-    pParty->vPosition.y = v117;
+    pParty->vPosition.y = pY;
 LABEL_313:
     if ( bWaterWalk )
     {
@@ -3255,10 +3241,10 @@
     pParty->field_6F8 = 64;
   }
 LABEL_318:
-  v81 = v123;
-  v82 = v123;
-  pParty->vPosition.z = v123;
-  if ( v123 > 8160 )
+  v81 = pZ;
+  v82 = pZ;
+  pParty->vPosition.z = pZ;
+  if ( pZ > 8160 )
   {
     v82 = 8160;
     pParty->uFallStartY = 8160;
@@ -3275,8 +3261,8 @@
       pParty->uFlags |= 4u;
   }
   if ( !v103
-    || (EventProcessor(v103, 0, 1), pParty->vPosition.x == v116)
-    && pParty->vPosition.y == v117
+    || (EventProcessor(v103, 0, 1), pParty->vPosition.x == pX)
+    && pParty->vPosition.y == pY
     && (v82 = pParty->vPosition.z, pParty->vPosition.z == v81) )
   {
     if ( v82 < v111 )
--- a/mm7_4.cpp	Wed Mar 20 17:49:15 2013 +0600
+++ b/mm7_4.cpp	Thu Mar 21 16:09:44 2013 +0600
@@ -238,16 +238,8 @@
 // 6836C8: using guessed type int 6836C8_num_decorations_6807E8;
 
 //----- (0046CEC3) --------------------------------------------------------
-int _46CEC3_get_floor_level(int x, int y, int z, unsigned int uSectorID, unsigned int *pFaceID)
-{
-  //BLVSector *v5; // edi@1
-  //int v6; // ecx@1
-  //Vec3_short_ *v7; // edx@1
-  //BLVFace *v8; // esi@2
-  //int v9; // eax@8
-  //int v10; // edi@8
-  //int v11; // eax@10
-  int v12; // ecx@10
+int BLV_GetFloorLevel(int x, int y, int z, unsigned int uSectorID, unsigned int *pFaceID)
+{
   int v13; // ecx@13
   signed int v14; // ebx@14
   int v15; // eax@16
@@ -255,14 +247,8 @@
   int v17; // ST18_4@19
   signed int v18; // edx@19
   signed __int64 v19; // qtt@19
-  PolygonType v20; // al@25
   int v21; // eax@27
   int v22; // ecx@29
-  //BLVFace *v23; // eax@33
-  //int v24; // esi@39
-  //int v25; // edi@39
-  //int v26; // esi@41
-  int v27; // ecx@43
   signed int v28; // eax@45
   int v29; // ebx@47
   int v30; // edx@49
@@ -272,51 +258,22 @@
   signed int v34; // eax@54
   signed int v35; // esi@56
   int result; // eax@57
-  int pPartyOpp; // edi@61
   int v38; // edx@62
-  //int v39; // [sp+Ch] [bp-34h]@1
-  //int v40; // [sp+10h] [bp-30h]@2
-  int v41; // [sp+14h] [bp-2Ch]@12
-  //unsigned __int16 *v42; // [sp+18h] [bp-28h]@1
-  //BLVSector *v43; // [sp+1Ch] [bp-24h]@1
   int v44; // [sp+20h] [bp-20h]@10
-  int v45; // [sp+24h] [bp-1Ch]@10
-  //signed int v46; // [sp+24h] [bp-1Ch]@38
   bool v47; // [sp+24h] [bp-1Ch]@43
   bool v48; // [sp+28h] [bp-18h]@10
   bool v49; // [sp+28h] [bp-18h]@41
   bool v50; // [sp+2Ch] [bp-14h]@12
-  int v51; // [sp+2Ch] [bp-14h]@41
-  //signed int v52; // [sp+30h] [bp-10h]@7
   signed int v53; // [sp+30h] [bp-10h]@10
   signed int v54; // [sp+30h] [bp-10h]@41
   signed int v55; // [sp+34h] [bp-Ch]@1
-  //signed int v56; // [sp+38h] [bp-8h]@1
-  //signed int v57; // [sp+3Ch] [bp-4h]@1
-  //int uSectorIDa; // [sp+4Ch] [bp+Ch]@1
-  //signed int uSectorIDb; // [sp+4Ch] [bp+Ch]@32
 
   LOG_DECOMPILATION_WARNING();
 
-  //auto a1 = x;
-  //auto a2 = y;
-  //auto a3 = z;
-
-  //v5 = &pIndoor->pSectors[uSectorID];
   auto pSector = &pIndoor->pSectors[uSectorID];
-  //v57 = y;
-  //v56 = x;
-  //v6 = 0;
-  v55 = 0;
-  //v43 = v5;
-  //v42 = v5->pFloors;
-  //v7 = pIndoor->pVertices;
-  //v39 = v5->uNumFloors;
-  //for ( uSectorIDa = 0; uSectorIDa < v39; ++uSectorIDa )
+  v55 = 1;
   for (uint i = 0; i < pSector->uNumFloors; ++i)
   {
-    //v40 = (int)&v42[v6];
-    //v8 = &pIndoor->pFaces[pSector->pFloors[i]];
     auto pFloor = &pIndoor->pFaces[pSector->pFloors[i]];
     if (pFloor->Clickable())
       continue;
@@ -324,85 +281,60 @@
     if (x <= pFloor->pBounding.x2 && x >= pFloor->pBounding.x1 &&
         y <= pFloor->pBounding.y2 && y >= pFloor->pBounding.y1)
     {
-      //v52 = 0;
       for (uint j = 0; j < pFloor->uNumVertices; ++j)
       {
-          //v9 = v52;
-          //v10 = 2 * v52;
         word_721460[2 * j] =     pFloor->pXInterceptDisplacements[j] + pIndoor->pVertices[pFloor->pVertexIDs[j]].x;
         word_721460[2 * j + 1] = pFloor->pXInterceptDisplacements[j] + pIndoor->pVertices[pFloor->pVertexIDs[j + 1]].x;
         word_721390[2 * j] =     pFloor->pYInterceptDisplacements[j] + pIndoor->pVertices[pFloor->pVertexIDs[j]].y;
         word_721390[2 * j + 1] = pFloor->pYInterceptDisplacements[j] + pIndoor->pVertices[pFloor->pVertexIDs[j + 1]].y;
-        //}
-        //while ( v52 < v8->uNumVertices );
-        //v5 = v43;
       }
       v44 = 2 * pFloor->uNumVertices;
-      //v11 = 2 * pFloor->uNumVertices;
       word_721460[2 * pFloor->uNumVertices] = word_721460[0];
       word_721390[2 * pFloor->uNumVertices] = word_721390[0];
 
       v48 = word_721390[0] >= y;
-      v12 = 0;
       v53 = 0;
-      v45 = 0;
       if ( pFloor->uNumVertices > 0 )
       {
-        do
+        for ( int i = 0; i < v44; i++ )
         {
           if ( v53 >= 2 )
             break;
-          v41 = word_721390[v12 + 1];
-          v50 = word_721390[v12 + 1] >= y;
+          v50 = word_721390[i + 1] >= y;
           if ( v48 == v50 )
           {
-            v13 = v45;
+            v13 = i;
           }
           else
           {
-            v13 = v45;
-            if ( word_721460[v45 + 1] >= x )
-              v14 = 0;
-            else
-              v14 = 2;
-            v15 = v14 | word_721460[v45] < x;
+            v13 = i;
+            v14 = word_721460[i + 1] >= x ? 0 : 2;
+            v15 = v14 | word_721460[i] < x;
             if ( v15 != 3 )
             {
-              if ( !v15
-                || (v16 = word_721390[v45],
-                    v17 = v41 - v16,
-                    v18 = y - v16,
-                    LODWORD(v19) = v18 << 16,
-                    HIDWORD(v19) = v18 >> 16,
-                    //v7 = pIndoor->pVertices,
-                    (signed int)(((unsigned __int64)(((signed int)word_721460[v45 + 1] - (signed int)word_721460[v45])
-                                                   * v19
-                                                   / v17) >> 16)
-                               + word_721460[v45]) >= x) )
-                ++v53;
+              if ( !v15 )
+              {
+                LODWORD(v19) = (y - word_721390[i]) << 16;
+                HIDWORD(v19) = (y - word_721390[i]) >> 16;
+                v16 = ((((word_721460[i + 1] - word_721460[i]) * v19 / (word_721390[i + 1] - word_721390[i])) >> 16) + word_721460[i]);
+                if ( v16 >= x)
+                  ++v53;
+              }
             }
           }
-          v12 = v13 + 1;
           v48 = v50;
-          v45 = v12;
-        }
-        while ( v12 < v44 );
-
+        }
         if ( v53 == 1 )
         {
           if ( v55 >= 50 )
             break;
-          v20 = pFloor->uPolygonType;
-          if ( v20 == 3 || v20 == 5 )
+          if ( pFloor->uPolygonType == POLYGON_Floor || pFloor->uPolygonType == POLYGON_Ceiling )
           {
             v21 = pIndoor->pVertices[*pFloor->pVertexIDs].z;
           }
           else
           {
-            //v7 = pIndoor->pVertices;
-            v21 = ((unsigned __int64)(pFloor->zCalc1 * (signed __int64)x) >> 16)
-                + ((unsigned __int64)(pFloor->zCalc2 * (signed __int64)y) >> 16)
-                + HIWORD(pFloor->zCalc3);
+            v21 = ((pFloor->zCalc1 * x) >> 16) + ((pFloor->zCalc2 * y) >> 16) + pFloor->zCalc3;
           }
           v22 = v55++;
           dword_7212C8[v22] = v21;
@@ -410,79 +342,53 @@
         }
       }
     }
-    //v6 = uSectorIDa + 1;
   }
 
   if ( pSector->field_0 & 8 )
   {
     for (uint i = 0; i < pSector->uNumPortals; ++i)
     {
-      //v23 = &pIndoor->pFaces[v5->pPortals[uSectorIDb]];
       auto portal = &pIndoor->pFaces[pSector->pPortals[i]];
       if (portal->uPolygonType != POLYGON_Floor)
         continue;
 
-      if (x <= portal->pBounding.x2 &&
-          x >= portal->pBounding.x1 &&
-          y <= portal->pBounding.y2 &&
-          y >= portal->pBounding.y1 )
-      {
-        //v46 = 0;
+      if (x <= portal->pBounding.x2 && x >= portal->pBounding.x1 &&
+          y <= portal->pBounding.y2 && y >= portal->pBounding.y1 )
+      {
         for (uint j = 0; j < portal->uNumVertices; ++j)
         {
-            //v24 = v46;
-            //v25 = 2 * v46;
           word_721460[2 * j] =     portal->pXInterceptDisplacements[j] + pIndoor->pVertices[portal->pVertexIDs[j]].x;
           word_721460[2 * j + 1] = portal->pXInterceptDisplacements[j + 1] + pIndoor->pVertices[portal->pVertexIDs[j + 1]].x;
           word_721390[2 * j] =     portal->pYInterceptDisplacements[j] + pIndoor->pVertices[portal->pVertexIDs[j]].y;
           word_721390[2 * j + 1] = portal->pYInterceptDisplacements[j + 1] + pIndoor->pVertices[portal->pVertexIDs[j + 1]].y;
-          //}
-          //while ( v46 < v23->uNumVertices );
-          //v5 = v43;
-        }
-
-        //v26 = 2 * v23->uNumVertices;
+        }
         word_721460[2 * portal->uNumVertices] = word_721460[0];
         word_721390[2 * portal->uNumVertices] = word_721390[0];
         v54 = 0;
-        v51 = 0;
         v49 = word_721390[0] >= y;
         if ( portal->uNumVertices > 0 )
         {
-          do
+          for ( int i = 0; i < 2 * portal->uNumVertices; ++i )
           {
             if ( v54 >= 2 )
               break;
-            v27 = v51;
-            v47 = word_721390[v51 + 1] >= y;
+            v47 = word_721390[i + 1] >= y;
             if ( v49 != v47 )
             {
-              if ( word_721460[v27 + 1] >= x )
-                v28 = 0;
-              else
-                v28 = 2;
-              v29 = v28 | word_721460[v27] < x;
+              v28 = word_721460[i + 1] >= x ? 0 : 2;
+              v29 = v28 | word_721460[i] < x;
               if ( v29 != 3 )
               {
-                if ( !v29
-                  || (v30 = word_721390[v27],
-                      v31 = word_721390[v51 + 1] - v30,
-                      v32 = y - v30,
-                      LODWORD(v33) = v32 << 16,
-                      HIDWORD(v33) = v32 >> 16,
-                      //v7 = pIndoor->pVertices,
-                      (signed int)(((unsigned __int64)(((signed int)word_721460[v27 + 1] - (signed int)word_721460[v27])
-                                                     * v33
-                                                     / v31) >> 16)
-                                 + word_721460[v27]) >= x) )
-                  ++v54;
+                if ( !v29 )
+                  LODWORD(v33) = (y - word_721390[i]) << 16;
+                  HIDWORD(v33) = (y - word_721390[i]) >> 16;
+                  v30 = ((((word_721460[i + 1] - word_721460[i]) * v33 / (word_721390[i + 1] - word_721390[i])) >> 16) + word_721460[i]);
+                  if ( v30 >= x)
+                    ++v54;
               }
             }
-            ++v51;
             v49 = v47;
           }
-          while ( v51 < 2 * portal->uNumVertices );
-
           if ( v54 == 1 )
           {
             if ( v55 >= 50 )
@@ -495,8 +401,6 @@
       }
     }
   }
-
-  //v35 = 1;
   if ( v55 == 1 )
   {
     *pFaceID = dword_721200[0];
@@ -508,47 +412,32 @@
   result = dword_7212C8[0];
   if ( v55 > 1 )
   {
-    pPartyOpp = z + 5;
-    //while ( 1 )
     for ( v35 = 1; v35 < v55; ++v35 )
     {
-      v38 = dword_7212C8[v35];
-      if ( result <= pPartyOpp )
-      {
-        if ( v38 >= result || v38 > pPartyOpp )
+      if ( result <= z + 5 )
+      {
+        if ( dword_7212C8[v35] >= result || dword_7212C8[v35] > z + 5 )
           continue;
         result = dword_7212C8[v35];
         *pFaceID = dword_721200[v35];
         continue;
       }
-      if ( v38 < result )
+      if ( dword_7212C8[v35] < result )
       {
         result = dword_7212C8[v35];
         *pFaceID = dword_721200[v35];
       }
-//LABEL_68:
-      //++v35;
-      //if ( v35 >= v55 )
-        //return result;
     }
   }
   return result;
 }
 
 //----- (0046D49E) --------------------------------------------------------
-int __fastcall sub_46D49E_prolly_get_world_y_under_party(int a1, signed int a2, int a3, int a4, int *a5, int *a6, int a7)
-{
-  signed int v7; // edi@1
-  int v8; // ebx@1
-  int v9; // eax@1
-  BSPModel *v10; // esi@4
-  ODMFace *v11; // ecx@11
-  unsigned __int8 v12; // al@11
-  char *v13; // eax@19
+int __fastcall ODM_GetFloorLevel(int X, signed int Y, int Z, int a4, int *a5, int *a6, int a7)
+{
+  BSPModel *pBModel; // esi@4
+  ODMFace *pFace; // ecx@11
   int v14; // edx@20
-  int v15; // eax@22
-  int v16; // edx@22
-  int v17; // edi@24
   signed int v18; // edx@26
   int v19; // eax@28
   int v20; // edx@30
@@ -565,201 +454,149 @@
   int v31; // eax@45
   ODMFace *v32; // eax@57
   int v33; // ecx@59
-  int v34; // [sp+Ch] [bp-34h]@8
-  int v35; // [sp+10h] [bp-30h]@22
   int v36; // [sp+14h] [bp-2Ch]@24
-  int v37; // [sp+18h] [bp-28h]@22
   int v38; // [sp+1Ch] [bp-24h]@2
   int v39; // [sp+20h] [bp-20h]@9
-  int v40; // [sp+24h] [bp-1Ch]@1
-  signed int v41; // [sp+28h] [bp-18h]@1
-  int v42; // [sp+2Ch] [bp-14h]@8
+  signed int pBModelNum; // [sp+28h] [bp-18h]@1
+  int pFaceNum; // [sp+2Ch] [bp-14h]@8
   bool v43; // [sp+30h] [bp-10h]@22
   bool v44; // [sp+34h] [bp-Ch]@24
-  signed int v45; // [sp+38h] [bp-8h]@1
   signed int v46; // [sp+3Ch] [bp-4h]@1
-  signed int v47; // [sp+58h] [bp+18h]@18
   signed int v48; // [sp+58h] [bp+18h]@22
   signed int v49; // [sp+58h] [bp+18h]@43
 
-  v7 = a2;
-  v8 = a1;
-  v45 = a2;
-  v40 = a1;
   v46 = 1;
-  v9 = GetTerrainHeightsAroundParty2(a1, a2, a5, a7);
   dword_721160[0] = -1;
   dword_721110[0] = -1;
-  dword_7211B0[0] = v9;
-  v41 = 0;
+  floor_level[0] = GetTerrainHeightsAroundParty2(X, Y, a5, a7);
   if ( (signed int)pOutdoor->uNumBModels <= 0 )
-    goto LABEL_63;
+  {
+    *a6 = 0;
+    return floor_level[0];
+  }
   v38 = 0;
-  while ( 1 )
-  {
-    v10 = &pOutdoor->pBModels[v38];
-    if ( v8 <= pOutdoor->pBModels[v38].sMaxX )
-    {
-      if ( v8 >= v10->sMinX )
-      {
-        if ( v7 <= v10->sMaxY )
-        {
-          if ( v7 >= v10->sMinY )
+  for ( pBModelNum = 0; pBModelNum < (signed int)pOutdoor->uNumBModels; ++pBModelNum )
+  {
+    pBModel = &pOutdoor->pBModels[v38];
+    if ( X <= pBModel->sMaxX && X >= pBModel->sMinX && Y <= pBModel->sMaxY && Y >= pBModel->sMinY )
+    {
+      if ( (signed int)pBModel->uNumFaces > 0 )
+      {
+        v39 = 0;
+        for ( pFaceNum = 0; pFaceNum < pBModel->uNumFaces; ++pFaceNum )
+        {
+          pFace = &pBModel->pFaces[v39];
+          if ( (pFace->uPolygonType == POLYGON_Floor || pFace->uPolygonType == POLYGON_InBetweenFloorAndWall)
+            && !(pFace->uAttributes & 0x20000000)
+            && X <= pFace->pBoundingBox.x2 && X >= pFace->pBoundingBox.x1
+            && Y <= pFace->pBoundingBox.y2 && Y >= pFace->pBoundingBox.y1 )
           {
-            v42 = 0;
-            v34 = v10->uNumFaces;
-            if ( (signed int)v10->uNumFaces > 0 )
+            if ( pFace->uNumVertices )
             {
-              v39 = 0;
-              while ( 1 )
+              for ( uint i = 0; i < pFace->uNumVertices; ++i)
               {
-                v11 = &v10->pFaces[v39];
-                v12 = v11->uPolygonType;
-                if ( (v12 == 3 || v12 == 4)
-                  && !(v11->uAttributes & 0x20000000)
-                  && v8 <= v11->pBoundingBox.x2
-                  && v8 >= v11->pBoundingBox.x1
-                  && v7 <= v11->pBoundingBox.y2
-                  && v7 >= v11->pBoundingBox.y1 )
+                word_721040[2 * i] = pFace->pXInterceptDisplacements[i] + pBModel->pVertices.pVertices[pFace->pVertexIDs[i]].x;
+                word_720F70[2 * i] = pFace->pXInterceptDisplacements[i + 1] + pBModel->pVertices.pVertices[pFace->pVertexIDs[i]].y;
+                word_721040[2 * i + 1] = pFace->pXInterceptDisplacements[i] + pBModel->pVertices.pVertices[pFace->pVertexIDs[i + 1]].x;
+                word_720F70[2 * i + 1] = pFace->pXInterceptDisplacements[i + 1] + pBModel->pVertices.pVertices[pFace->pVertexIDs[i + 1]].y;
+              }
+            }
+            word_721040[2 * pFace->uNumVertices] = word_721040[0];
+            word_720F70[2 * pFace->uNumVertices] = word_720F70[0];
+            v43 = word_720F70[0] >= Y;
+            v48 = 0;
+            if ( 2 * pFace->uNumVertices > 0 )
+            {
+              for ( int i = 0; i < 2 * pFace->uNumVertices; ++i )
+              {
+                if ( v48 >= 2 )
+                  break;
+                v36 = word_720F70[i + 1];
+                v44 = word_720F70[i + 1] >= Y;
+                if ( v43 != v44 )
                 {
-                  v47 = 0;
-                  if ( v11->uNumVertices )
+                  v18 = word_721040[i + 1] >= X ? 0 : 2;
+                  v19 = v18 | word_721040[i] < X;
+                  if ( v19 != 3 )
                   {
-                    v13 = (char *)v11->pXInterceptDisplacements;
-                    do
+                    if ( !v19 )
                     {
-                      v14 = 2 * v47;
-                      word_721040[2 * v47] = *(short *)v13 + LOWORD(v10->pVertices.pVertices[*((short *)v13 - 60)].x);
-                      word_720F70[2 * v47] = *((short *)v13 + 20)
-                                           + LOWORD(v10->pVertices.pVertices[*((short *)v13 - 60)].y);
-                      word_721040[2 * v47++ + 1] = *(short *)v13
-                                                 + LOWORD(v10->pVertices.pVertices[*((short *)v13 - 59)].x);
-                      word_720F70[v14 + 1] = *((short *)v13 + 20)
-                                           + LOWORD(v10->pVertices.pVertices[*((short *)v13 - 59)].y);
-                      v13 += 2;
-                    }
-                    while ( v47 < v11->uNumVertices );
-                    v8 = v40;
-                  }
-                  v15 = 2 * v11->uNumVertices;
-                  word_721040[2 * v11->uNumVertices] = word_721040[0];
-                  word_720F70[v15] = word_720F70[0];
-                  v35 = v15;
-                  v16 = 0;
-                  v43 = word_720F70[0] >= v45;
-                  v48 = 0;
-                  v37 = 0;
-                  if ( v15 > 0 )
-                  {
-                    do
-                    {
-                      if ( v48 >= 2 )
-                        break;
-                      v17 = v16;
-                      v8 = v40;
-                      v36 = word_720F70[v16 + 1];
-                      v44 = word_720F70[v16 + 1] >= v45;
-                      if ( v43 != v44 )
-                      {
-                        v18 = word_721040[v17 + 1] >= v40 ? 0 : 2;
-                        v19 = v18 | word_721040[v17] < v40;
-                        if ( v19 != 3 )
-                        {
-                          if ( !v19
-                            || (v20 = word_720F70[v17],
-                                v21 = v36 - v20,
-                                v22 = v45 - v20,
-                                LODWORD(v23) = v22 << 16,
-                                HIDWORD(v23) = v22 >> 16,
-                                (signed int)(((unsigned __int64)(((signed int)word_721040[v17 + 1]
-                                                                - (signed int)word_721040[v17])
-                                                               * v23
-                                                               / v21) >> 16)
-                                           + word_721040[v17]) >= v40) )
-                            ++v48;
-                        }
-                      }
-                      v16 = v37 + 1;
-                      v43 = v44;
-                      ++v37;
-                    }
-                    while ( v37 < v35 );
-                    if ( v48 == 1 )
-                    {
-                      if ( v46 >= 20 )
-                        break;
-                      if ( v11->uPolygonType == 3 )
-                        v24 = v10->pVertices.pVertices[v11->pVertexIDs[0]].z;
-                      else
-                        v24 = ((unsigned __int64)(v11->zCalc1 * (signed __int64)v8) >> 16)
-                            + ((unsigned __int64)(v11->zCalc2 * (signed __int64)v45) >> 16)
-                            + HIWORD(v11->zCalc3);
-                      v25 = v46++;
-                      dword_7211B0[v25] = v24;
-                      dword_721160[v25] = v41;
-                      dword_721110[v25] = v42;
+                      LODWORD(v23) = (Y - word_720F70[i]) << 16;
+                      HIDWORD(v23) = (Y - word_720F70[i]) >> 16;
+                      v22 = ((((word_721040[i + 1] - word_721040[i]) * v23 / (v36 - word_720F70[i])) >> 16) + word_721040[i]);
+                      if ( v22 >= X) 
+                        ++v48;
                     }
                   }
                 }
-                ++v42;
-                ++v39;
-                if ( v42 >= v34 )
+                v43 = v44;
+              }
+              if ( v48 == 1 )
+              {
+                if ( v46 >= 20 )
                   break;
-                v7 = v45;
+                if ( pFace->uPolygonType == POLYGON_Floor )
+                  v24 = pBModel->pVertices.pVertices[pFace->pVertexIDs[0]].z;
+                else
+                  v24 = ((pFace->zCalc1 * X) >> 16) + ((pFace->zCalc2 * Y) >> 16) + pFace->zCalc3;
+                v25 = v46++;
+                floor_level[v25] = v24;
+                dword_721160[v25] = pBModelNum;
+                dword_721110[v25] = pFaceNum;
               }
             }
           }
-        }
-      }
-    }
-    ++v41;
+          ++v39;
+        }
+      }
+    }
     ++v38;
-    if ( v41 >= (signed int)pOutdoor->uNumBModels )
-      break;
-    v7 = v45;
   }
   if ( v46 == 1 )
   {
-LABEL_63:
     *a6 = 0;
-    return dword_7211B0[0];
+    return floor_level[0];
   }
   v27 = 0;
-  v49 = 1;
   if ( v46 <= 1 )
-  {
-LABEL_55:
     *a6 = 0;
-    goto LABEL_56;
-  }
-  v28 = 0;
-  v29 = 1;
-  do
-  {
-    v30 = dword_7211B0[v29];
-    v31 = *(int *)((char *)dword_7211B0 + v28);
-    if ( v30 == v31 )
-      goto LABEL_51;
-    if ( v31 > a3 + 5 )
-    {
-      if ( v30 >= v31 )
-        goto LABEL_52;
-LABEL_51:
-      v27 = v49;
-      v28 = v29 * 4;
-      goto LABEL_52;
-    }
-    if ( v30 > v31 && v30 <= a3 + 5 )
-      goto LABEL_51;
-LABEL_52:
-    ++v49;
-    ++v29;
-  }
-  while ( v49 < v46 );
-  if ( !v27 )
-    goto LABEL_55;
-  *a6 = dword_721110[v27] | (dword_721160[v27] << 6);
-LABEL_56:
+  else
+  {
+    v28 = 0;
+    v29 = 1;
+    for ( v49 = 1; v49 < v46; ++v49 )
+    {
+      if ( floor_level[v29] == floor_level[v28] )
+      {
+        v27 = v49;
+        v28 = v29 * 4;
+        ++v29;
+        break;
+      }
+      if ( floor_level[v28] > Z + 5 )
+      {
+        if ( floor_level[v29] >= floor_level[v28] )
+        {
+          ++v29;
+          break;
+        }
+        v27 = v49;
+        v28 = v29 * 4;
+        ++v29;
+        break;
+      }
+      if ( floor_level[v29] > floor_level[v28] && floor_level[v29] <= Z + 5 )
+      {
+        v27 = v49;
+        v28 = v29 * 4;
+        ++v29;
+      }
+    }
+    if ( !v27 )
+      *a6 = 0;
+    else
+      *a6 = dword_721110[v27] | (dword_721160[v27] << 6);
+  }
   if ( v27 )
   {
     v32 = &pOutdoor->pBModels[dword_721160[v27]].pFaces[dword_721110[v27]];
@@ -767,9 +604,9 @@
     if ( v32->uAttributes & 0x10 )
       *a5 = 1;
   }
-  v33 = dword_7211B0[v27];
-  result = dword_7211B0[0];
-  if ( v33 >= dword_7211B0[0] )
+  v33 = floor_level[v27];
+  result = floor_level[0];
+  if ( v33 >= floor_level[0] )
     result = v33;
   return result;
 }
--- a/mm7_data.cpp	Wed Mar 20 17:49:15 2013 +0600
+++ b/mm7_data.cpp	Thu Mar 21 16:09:44 2013 +0600
@@ -2040,7 +2040,7 @@
 __int16 word_721040[777]; // idb
 int dword_721110[777]; // idb
 int dword_721160[777]; // idb
-int dword_7211B0[777]; // idb
+int floor_level[20]; // idb
 int dword_721200[777]; // idb
 int dword_7212C8[777]; // idb
 __int16 word_721390[104]; // idb
--- a/mm7_data.h	Wed Mar 20 17:49:15 2013 +0600
+++ b/mm7_data.h	Thu Mar 21 16:09:44 2013 +0600
@@ -1557,7 +1557,7 @@
 extern __int16 word_721040[]; // idb
 extern int dword_721110[]; // idb
 extern int dword_721160[]; // idb
-extern int dword_7211B0[]; // idb
+extern int floor_level[20]; // idb dword_7211B0
 extern int dword_721200[]; // idb
 extern int dword_7212C8[]; // idb
 extern __int16 word_721390[]; // idb
@@ -2149,8 +2149,8 @@
 void __cdecl ODM_UpdateUserInputAndOther();
 bool __fastcall _46BFFA_check_object_intercept(unsigned int uLayingItemID, signed int a2);
 void __cdecl _46CC4B_check_event_triggers();
-int _46CEC3_get_floor_level(int x, int y, int z, unsigned int uSectorID, unsigned int *pFaceID);
-int __fastcall sub_46D49E_prolly_get_world_y_under_party(int a1, signed int a2, int a3, int a4, int *a5, int *a6, int a7);
+int BLV_GetFloorLevel(int x, int y, int z, unsigned int uSectorID, unsigned int *pFaceID);
+int __fastcall ODM_GetFloorLevel(int X, signed int Y, int Z, int a4, int *a5, int *a6, int a7);
 int __fastcall sub_46D8E3(int a1, signed int a2, int a3, int a4);
 void ODM_GetTerrainNormalAt(int pos_x, int pos_z, Vec3_int_ *out);
 unsigned int __fastcall sub_46DEF2(signed int a2, unsigned int uLayingItemID);